Я пытаюсь реализовать интеграционное тестирование в. net ядре 3.1 с двумя API-проектами. Пожалуйста, найдите структуру решения, как показано ниже:
AuthenticationService предоставляет JWT, который мы используем для аутентификации запроса, при вызове любой функции TweetBookService означает, что TweetBookService зависит от AuthenticationService для JWT.
В проекте 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);
}
}
});
}
}
. Чтобы получить JWT из AuthenticationService в проекте Testing, я создал класс 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, который наследуется от класса IntegrationTest для JWT, но получает ошибку в конструкторе из-за двух разных 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 в другом проекте или как сделать интеграционное тестирование в микросервисе.