重构单元测试和集成测试
This commit is contained in:
1 parent
e7e9afe11b
commit
81c8f608dc
34 files changed
+135
-300
No files matched your search
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Interceptors;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace HelloShop.BasketService.FunctionalTests
|
||||
{
|
||||
internal class AuthenticatedInterceptor : Interceptor
|
||||
{
|
||||
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
|
||||
{
|
||||
const string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxIiwidW5pcXVlX25hbWUiOiJhZG1pbiIsInJvbGVpZCI6IjEiLCJuYmYiOjE3MjA1NzY3NDYsImV4cCI6MTc0MjYwODc0NiwiaWF0IjoxNzIwNTc2NzQ2fQ.ju_D3zeGLKqJYVckbb8Y3yNkp40nOqRAJrdOsISs4d4";
|
||||
|
||||
Metadata headers = [new Metadata.Entry(HeaderNames.Authorization, $"Bearer {token}")];
|
||||
|
||||
var newOptions = context.Options.WithHeaders(headers);
|
||||
|
||||
var newContext = new ClientInterceptorContext<TRequest, TResponse>(context.Method, context.Host, newOptions);
|
||||
|
||||
return base.AsyncUnaryCall(request, newContext, continuation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Grpc.Core;
|
||||
using Grpc.Core.Interceptors;
|
||||
using Grpc.Net.Client;
|
||||
using HelloShop.BasketService.Protos;
|
||||
|
||||
namespace HelloShop.BasketService.FunctionalTests
|
||||
{
|
||||
public class BasketServiceIntegrationTest
|
||||
{
|
||||
private readonly Basket.BasketClient _client;
|
||||
|
||||
public BasketServiceIntegrationTest()
|
||||
{
|
||||
GrpcChannel channel = GrpcChannel.ForAddress(GrpcConstants.GrpcAddress);
|
||||
CallInvoker invoker = channel.Intercept(new AuthenticatedInterceptor());
|
||||
_client = new Basket.BasketClient(invoker);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetBasketReturnsBasket()
|
||||
{
|
||||
// Arrange
|
||||
var request = new Empty();
|
||||
|
||||
// Act
|
||||
var reply = await _client.GetBasketAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(reply);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateBasketReturnsBasketResponse()
|
||||
{
|
||||
// Arrange
|
||||
var request = new UpdateBasketRequest
|
||||
{
|
||||
Items =
|
||||
{
|
||||
new BasketListItem { ProductId = 1, Quantity = 2 },
|
||||
new BasketListItem { ProductId = 2, Quantity = 3 }
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
var reply = await _client.UpdateBasketAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, reply.Items.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DeleteBasketReturnsEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var request = new Empty();
|
||||
|
||||
// Act
|
||||
var reply = await _client.DeleteBasketAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using Grpc.Net.Client;
|
||||
using HelloShop.BasketService.Protos;
|
||||
|
||||
namespace HelloShop.BasketService.FunctionalTests
|
||||
{
|
||||
public class GreeterServiceIntegrationTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task SayHelloReturnsHelloMessage()
|
||||
{
|
||||
// Arrange
|
||||
using var channel = GrpcChannel.ForAddress(GrpcConstants.GrpcAddress);
|
||||
var client = new Greeter.GreeterClient(channel);
|
||||
|
||||
// Act
|
||||
var reply = await client.SayHelloAsync(new HelloRequest { Name = "Greeter" });
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Hello Greeter", reply.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
namespace HelloShop.BasketService.FunctionalTests
|
||||
{
|
||||
internal class GrpcConstants
|
||||
{
|
||||
public const string GrpcAddress = "http://localhost:8004";
|
||||
}
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.21.5" />
|
||||
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.49.0" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.49.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Grpc.JsonTranscoding" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="xunit" Version="2.5.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\..\src\HelloShop.BasketService\Protos\basket.proto" GrpcServices="Client">
|
||||
<Link>Protos\basket.proto</Link>
|
||||
</Protobuf>
|
||||
<Protobuf Include="..\..\src\HelloShop.BasketService\Protos\greet.proto" GrpcServices="Client">
|
||||
<Link>Protos\greet.proto</Link>
|
||||
</Protobuf>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<IncludeHttpRuleProtos>true</IncludeHttpRuleProtos>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.30.1" />
|
||||
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.70.0" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.71.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Grpc.JsonTranscoding" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\..\src\HelloShop.BasketService\Protos\basket.proto" GrpcServices="Client">
|
||||
<Link>Protos\basket.proto</Link>
|
||||
</Protobuf>
|
||||
<Protobuf Include="..\..\src\HelloShop.BasketService\Protos\greet.proto" GrpcServices="Client">
|
||||
<Link>Protos\greet.proto</Link>
|
||||
</Protobuf>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -2,6 +2,8 @@
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using AutoMapper;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using HelloShop.BasketService.AutoMapper;
|
||||
using HelloShop.BasketService.Entities;
|
||||
@@ -25,7 +27,8 @@ namespace HelloShop.BasketService.UnitTests.Services
|
||||
var basketRepositoryMock = new Mock<IBasketRepository>();
|
||||
var loggerMock = NullLogger<CustomerBasketService>.Instance;
|
||||
var mapperMock = new Mock<IMapper>();
|
||||
var service = new CustomerBasketService(basketRepositoryMock.Object, loggerMock, mapperMock.Object);
|
||||
var validatorMock = new Mock<IValidator<UpdateBasketRequest>>();
|
||||
var service = new CustomerBasketService(basketRepositoryMock.Object, loggerMock, mapperMock.Object, validatorMock.Object);
|
||||
|
||||
TestServerCallContext serverCallContext = TestServerCallContext.Create();
|
||||
|
||||
@@ -50,11 +53,13 @@ namespace HelloShop.BasketService.UnitTests.Services
|
||||
var basketRepositoryMock = new Mock<IBasketRepository>();
|
||||
basketRepositoryMock.Setup(x => x.GetBasketAsync(It.IsAny<int>(), It.IsAny<CancellationToken>())).ReturnsAsync(new CustomerBasket() { BuyerId = 1, Items = [new BasketItem { ProductId = 1, Quantity = 1 }] });
|
||||
|
||||
var validatorMock = new Mock<IValidator<UpdateBasketRequest>>();
|
||||
|
||||
var logger = NullLogger<CustomerBasketService>.Instance;
|
||||
|
||||
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>()));
|
||||
|
||||
var service = new CustomerBasketService(basketRepositoryMock.Object, logger, mapper);
|
||||
var service = new CustomerBasketService(basketRepositoryMock.Object, logger, mapper, validatorMock.Object);
|
||||
|
||||
TestServerCallContext serverCallContext = TestServerCallContext.Create();
|
||||
|
||||
@@ -82,7 +87,10 @@ namespace HelloShop.BasketService.UnitTests.Services
|
||||
var logger = NullLogger<CustomerBasketService>.Instance;
|
||||
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>()));
|
||||
|
||||
var service = new CustomerBasketService(basketRepositoryMock.Object, logger, mapper);
|
||||
var validatorMock = new Mock<IValidator<UpdateBasketRequest>>();
|
||||
validatorMock.Setup(x => x.ValidateAsync(It.IsAny<UpdateBasketRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(new ValidationResult());
|
||||
|
||||
var service = new CustomerBasketService(basketRepositoryMock.Object, logger, mapper, validatorMock.Object);
|
||||
|
||||
TestServerCallContext serverCallContext = TestServerCallContext.Create();
|
||||
|
||||
@@ -112,7 +120,10 @@ namespace HelloShop.BasketService.UnitTests.Services
|
||||
var basketRepositoryMock = new Mock<IBasketRepository>();
|
||||
var logger = NullLogger<CustomerBasketService>.Instance;
|
||||
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>()));
|
||||
var service = new CustomerBasketService(basketRepositoryMock.Object, logger, mapper);
|
||||
|
||||
var validatorMock = new Mock<IValidator<UpdateBasketRequest>>();
|
||||
|
||||
var service = new CustomerBasketService(basketRepositoryMock.Object, logger, mapper, validatorMock.Object);
|
||||
|
||||
TestServerCallContext serverCallContext = TestServerCallContext.Create();
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using Aspire.Hosting;
|
||||
using Aspire.Hosting.ApplicationModel;
|
||||
using HelloShop.FunctionalTests.Helpers;
|
||||
using Microsoft.AspNetCore.Authentication.BearerToken;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Dynamic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
@@ -11,18 +13,24 @@ using System.Text.Json.Nodes;
|
||||
|
||||
namespace HelloShop.FunctionalTests
|
||||
{
|
||||
public class FirstWebApiIntegrationTest
|
||||
public class FirstWebApiIntegrationTest(TestingAspireAppHost app) : IAsyncLifetime, IClassFixture<TestingAspireAppHost>
|
||||
{
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await app.StartAsync();
|
||||
}
|
||||
|
||||
public async Task DisposeAsync() => await Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
public async Task WebAppRootReturnsOkStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
IDistributedApplicationTestingBuilder appHost = await DistributedApplicationTestingBuilder.CreateAsync<Projects.HelloShop_AppHost>();
|
||||
await using DistributedApplication app = await appHost.BuildAsync();
|
||||
await app.StartAsync();
|
||||
var resourceNotificationService = app.Services.GetRequiredService<ResourceNotificationService>();
|
||||
|
||||
// Act
|
||||
HttpClient httpClient = app.CreateHttpClient("webapp");
|
||||
await resourceNotificationService.WaitForResourceAsync("webapp", KnownResourceStates.Running).WaitAsync(TimeSpan.FromSeconds(30));
|
||||
HttpResponseMessage response = await httpClient.GetAsync("/");
|
||||
|
||||
// Assert
|
||||
@@ -33,12 +41,11 @@ namespace HelloShop.FunctionalTests
|
||||
public async Task IdetityServiceAccountLoginReturnsSuccessStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
IDistributedApplicationTestingBuilder appHost = await DistributedApplicationTestingBuilder.CreateAsync<Projects.HelloShop_AppHost>();
|
||||
await using DistributedApplication app = await appHost.BuildAsync();
|
||||
await app.StartAsync();
|
||||
var resourceNotificationService = app.Services.GetRequiredService<ResourceNotificationService>();
|
||||
|
||||
// Act
|
||||
HttpClient httpClient = app.CreateHttpClient("identityservice");
|
||||
await resourceNotificationService.WaitForResourceHealthyAsync("identityservice").WaitAsync(TimeSpan.FromSeconds(30));
|
||||
HttpResponseMessage response = await httpClient.PostAsJsonAsync("api/Account/Login", new
|
||||
{
|
||||
UserName = "guest",
|
||||
@@ -53,12 +60,11 @@ namespace HelloShop.FunctionalTests
|
||||
public async Task IdetityServiceAccountLoginReturnsAccessToken()
|
||||
{
|
||||
// Arrange
|
||||
IDistributedApplicationTestingBuilder appHost = await DistributedApplicationTestingBuilder.CreateAsync<Projects.HelloShop_AppHost>();
|
||||
await using DistributedApplication app = await appHost.BuildAsync();
|
||||
await app.StartAsync();
|
||||
var resourceNotificationService = app.Services.GetRequiredService<ResourceNotificationService>();
|
||||
|
||||
// Act
|
||||
HttpClient httpClient = app.CreateHttpClient("identityservice");
|
||||
await resourceNotificationService.WaitForResourceHealthyAsync("identityservice").WaitAsync(TimeSpan.FromSeconds(30));
|
||||
HttpResponseMessage response = await httpClient.PostAsJsonAsync("api/Account/Login", new
|
||||
{
|
||||
UserName = "guest",
|
||||
@@ -74,13 +80,11 @@ namespace HelloShop.FunctionalTests
|
||||
public async Task IdetityServiceAccountLoginReturnsTokenExpiresInSeconds()
|
||||
{
|
||||
// Arrange
|
||||
IDistributedApplicationTestingBuilder appHost = await DistributedApplicationTestingBuilder.CreateAsync<Projects.HelloShop_AppHost>();
|
||||
await using DistributedApplication app = await appHost.BuildAsync();
|
||||
|
||||
await app.StartAsync();
|
||||
var resourceNotificationService = app.Services.GetRequiredService<ResourceNotificationService>();
|
||||
|
||||
// Act
|
||||
HttpClient httpClient = app.CreateHttpClient("identityservice");
|
||||
await resourceNotificationService.WaitForResourceHealthyAsync("identityservice").WaitAsync(TimeSpan.FromSeconds(30));
|
||||
HttpResponseMessage response = await httpClient.PostAsJsonAsync("api/Account/Login", new
|
||||
{
|
||||
UserName = "guest",
|
||||
@@ -97,13 +101,11 @@ namespace HelloShop.FunctionalTests
|
||||
public async Task ProductServiceGetProductReturnsProductDetails()
|
||||
{
|
||||
// Arrange
|
||||
IDistributedApplicationTestingBuilder appHost = await DistributedApplicationTestingBuilder.CreateAsync<Projects.HelloShop_AppHost>();
|
||||
|
||||
await using DistributedApplication app = await appHost.BuildAsync();
|
||||
await app.StartAsync();
|
||||
var resourceNotificationService = app.Services.GetRequiredService<ResourceNotificationService>();
|
||||
|
||||
// Act
|
||||
HttpClient identityServiceHttpClient = app.CreateHttpClient("identityservice");
|
||||
await resourceNotificationService.WaitForResourceHealthyAsync("identityservice").WaitAsync(TimeSpan.FromSeconds(30));
|
||||
HttpResponseMessage loginResponse = await identityServiceHttpClient.PostAsJsonAsync("api/Account/Login", new
|
||||
{
|
||||
UserName = "admin",
|
||||
@@ -114,16 +116,17 @@ namespace HelloShop.FunctionalTests
|
||||
|
||||
HttpClient productServiceHttpClient = app.CreateHttpClient("productservice");
|
||||
productServiceHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessTokenResponse?.AccessToken);
|
||||
await resourceNotificationService.WaitForResourceHealthyAsync("productservice").WaitAsync(TimeSpan.FromSeconds(30));
|
||||
|
||||
HttpResponseMessage productDetailsResponse = await productServiceHttpClient.GetAsync("api/Products/1");
|
||||
|
||||
JsonNode? result = await productDetailsResponse.Content.ReadFromJsonAsync<JsonNode>();
|
||||
|
||||
string? productName = result?["Name"]?.GetValue<string>();
|
||||
int? productId = result?["Id"]?.GetValue<int?>();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(productName);
|
||||
Assert.Equal("Product 1", productName);
|
||||
Assert.NotNull(productId);
|
||||
Assert.Equal(1, productId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using Aspire.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace HelloShop.FunctionalTests.Helpers
|
||||
{
|
||||
public class TestingAspireAppHost : DistributedApplicationFactory
|
||||
{
|
||||
private readonly TaskCompletionSource<IServiceProvider> _serviceTcs = new();
|
||||
|
||||
public TestingAspireAppHost() : base(typeof(Projects.HelloShop_AppHost)) { }
|
||||
|
||||
protected override void OnBuilderCreated(DistributedApplicationBuilder applicationBuilder)
|
||||
{
|
||||
applicationBuilder.Services.ConfigureHttpClientDefaults(clientBuilder =>
|
||||
{
|
||||
clientBuilder.AddStandardResilienceHandler();
|
||||
});
|
||||
}
|
||||
|
||||
protected override void OnBuilt(DistributedApplication application)
|
||||
{
|
||||
_serviceTcs.SetResult(application.Services);
|
||||
}
|
||||
|
||||
public IServiceProvider Services => _serviceTcs.Task.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using HelloShop.ProductService.FunctionalTests.Utilities;
|
||||
using HelloShop.ProductService.FunctionalTests.Helpers;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
@@ -31,8 +31,11 @@ namespace HelloShop.ProductService.FunctionalTests
|
||||
|
||||
// Act
|
||||
HttpResponseMessage response = await client.GetAsync("api/Brands/1");
|
||||
string responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
BrandDetailsResponse? brandDetails = await response.Content.ReadFromJsonAsync<BrandDetailsResponse>();
|
||||
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(brandDetails);
|
||||
Assert.Equal(1, brandDetails.Id);
|
||||
|
||||
+23
-10
@@ -7,40 +7,54 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Data.Common;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace HelloShop.ProductService.FunctionalTests.Utilities
|
||||
namespace HelloShop.ProductService.FunctionalTests.Helpers
|
||||
{
|
||||
public class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TProgram> where TProgram : class
|
||||
{
|
||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||
{
|
||||
builder.ConfigureServices(services =>
|
||||
builder.ConfigureServices(static services =>
|
||||
{
|
||||
ServiceDescriptor? dbContextDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<ProductServiceDbContext>));
|
||||
|
||||
var dbContextDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<ProductServiceDbContext>));
|
||||
if (dbContextDescriptor != null)
|
||||
{
|
||||
services.Remove(dbContextDescriptor);
|
||||
}
|
||||
|
||||
// Create open SqliteConnection so EF won't automatically close it.
|
||||
services.AddSingleton(container =>
|
||||
var dbConnectionDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbConnection));
|
||||
if (dbConnectionDescriptor != null)
|
||||
{
|
||||
DbConnection connection = new SqliteConnection("DataSource=:memory:");
|
||||
services.Remove(dbConnectionDescriptor);
|
||||
}
|
||||
|
||||
var optionsConfigurationDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IDbContextOptionsConfiguration<ProductServiceDbContext>));
|
||||
if (optionsConfigurationDescriptor != null)
|
||||
{
|
||||
services.Remove(optionsConfigurationDescriptor);
|
||||
}
|
||||
|
||||
// Create open SqliteConnection so EF won't automatically close it.
|
||||
services.AddSingleton<DbConnection>(container =>
|
||||
{
|
||||
var connection = new SqliteConnection("DataSource=file::memory:?cache=shared");
|
||||
connection.Open();
|
||||
|
||||
return connection;
|
||||
});
|
||||
|
||||
services.AddDbContext<ProductServiceDbContext>((container, options) =>
|
||||
services.AddDbContextPool<ProductServiceDbContext>((container, options) =>
|
||||
{
|
||||
var connection = container.GetRequiredService<DbConnection>();
|
||||
options.UseSqlite(connection);
|
||||
options.UseSqlite(connection).UseSnakeCaseNamingConvention();
|
||||
options.ConfigureWarnings(warnings => warnings.Ignore(RelationalEventId.PendingModelChangesWarning));
|
||||
});
|
||||
|
||||
services.Replace(ServiceDescriptor.Transient<IPermissionChecker, FakePermissionChecker>());
|
||||
@@ -52,7 +66,6 @@ namespace HelloShop.ProductService.FunctionalTests.Utilities
|
||||
protected override void ConfigureClient(HttpClient client)
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", FakeAccessTokenCreator.Create());
|
||||
|
||||
base.ConfigureClient(client);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@ using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
namespace HelloShop.ProductService.FunctionalTests.Utilities
|
||||
namespace HelloShop.ProductService.FunctionalTests.Helpers
|
||||
{
|
||||
public class FakeAccessTokenCreator
|
||||
{
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
using HelloShop.ProductService.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace HelloShop.ProductService.UnitTests.Utilities
|
||||
namespace HelloShop.ProductService.UnitTests.Helpers
|
||||
{
|
||||
public class FakeDbContextFactory : IDbContextFactory<ProductServiceDbContext>
|
||||
{
|
||||
@@ -7,7 +7,7 @@ using HelloShop.ProductService.Controllers;
|
||||
using HelloShop.ProductService.Entities.Products;
|
||||
using HelloShop.ProductService.Infrastructure;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
using HelloShop.ProductService.UnitTests.Utilities;
|
||||
using HelloShop.ProductService.UnitTests.Helpers;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace HelloShop.ProductService.UnitTests
|
||||
|
||||
Reference in new issue
Block a user