我试图通过两个API项目在.net core 3.1中实现集成测试。请找到以下解决方案的结构:
AuthenticationService提供了JWT,我们可以在调用TweetBookService的任何功能时对请求进行身份验证,这意味着TweetBookService依赖于JWT的AuthenticationService。
在TweetBook.IntegrationTesting项目中,我们创建了自定义WebApplicationFactory类:
public class CustomWebApplicationFactory<TStartup>
: WebApplicationFactory<TStartup> where TStartup : class
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// Remove the app's ApplicationDbContext registration.
var descriptor = services.SingleOrDefault(
d => d.ServiceType ==
typeof(DbContextOptions<ApplicationDbContext>));
if (descriptor != null)
{
services.Remove(descriptor);
}
// Add ApplicationDbContext using an in-memory database for testing.
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
});
// Build the service provider.
var sp = services.BuildServiceProvider();
// Create a scope to obtain a reference to the database
// context (ApplicationDbContext).
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<ApplicationDbContext>();
var logger = scopedServices
.GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();
// Ensure the database is created.
db.Database.EnsureCreated();
try
{
// Seed the database with test data.
Utilities.InitializeDbForTests(db);
}
catch (Exception ex)
{
logger.LogError(ex, "An error occurred seeding the " +
"database with test messages. Error: {Message}", ex.Message);
}
}
});
}
}
并且为了从Testing项目中的AuthenticationService获取JWT,我创建了IntegrationTest类 成功生成了JWT。
public class IntegrationTest : IClassFixture<CustomWebApplicationFactory<AuthenticationService.Startup>>
{
protected readonly HttpClient TestClient;
private readonly CustomWebApplicationFactory<AuthenticationService.Startup> _factory;
public IntegrationTest(CustomWebApplicationFactory<AuthenticationService.Startup> factory)
{
_factory = factory;
TestClient= _factory.CreateClient();
}
protected async Task AuthenticateAsync()
{
TestClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", await JwtTokenAsync());
}
private async Task<string> JwtTokenAsync()
{
string url = ApiRoutes.ControllerRoute + "/" + ApiRoutes.Identity.Register;
var response = await TestClient.PostAsJsonAsync(url, new UserRegisterationRequest
{
Email = "champ1@gmail.com",
Password = "Dotvik@9876"
});
var registerationResponse = await response.Content.ReadAsAsync<AuthSuccessResponse>();
return registerationResponse.JwtToken;
}
}
进一步获得实际的业务功能,我创建了PostControllerTest类,该类继承自JWT的IntegrationTest类,但由于两个不同的Startup.cs而在构造函数中出错
public class PostControllerTest : IntegrationTest
{
public PostControllerTest(CustomWebApplicationFactory<TweetBook.Startup> factory) : base(factory)
{
}
[Fact]
public async Task GetAll_WithoutAnyPosts_ReturnsEmptyRespose()
{
//Arrange
await AuthenticateAsync();
// Act
string url = ApiRoutes.ControllerRoute + "/" + ApiRoutes.Posts.GetAll;
var response = await TestClient.GetAsync(url);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
(await response.Content.ReadAsAsync<List<Post>>()).Should().BeEmpty();
}
}
请找到以下错误:
我也尝试使用TestServer(Microsoft.AspNetCore.Mvc.Testing),但没有成功。我该如何解决在不同项目中拥有不同Startup.cs的问题,或如何在微服务中进行集成测试。