Не удается преобразовать из WebApplicationFactory в WebApplicationFactory дюйм. net ядро - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь реализовать интеграционное тестирование в. net ядре 3.1 с двумя API-проектами. Пожалуйста, найдите структуру решения, как показано ниже:

enter image description here

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();
    }
}

Пожалуйста, найдите ошибку, как показано ниже:

enter image description here

Я также пытался использовать TestServer (Microsoft.AspNetCore. Mvc .Testing), но это не помогло. т работал. Как я могу решить эту проблему, имея разные Startup.cs в другом проекте или как сделать интеграционное тестирование в микросервисе.

...