无法从.net核心中的WebApplicationFactory <TweetBook.Startup>转换为WebApplicationFactory <AuthenticationService.Startup>

时间:2020-05-04 17:53:27

标签: .net-core jwt integration-testing asp.net-core-3.1 .net-core-3.1

我试图通过两个API项目在.net core 3.1中实现集成测试。请找到以下解决方案的结构:

enter image description here

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

请找到以下错误:

enter image description here

我也尝试使用TestServer(Microsoft.AspNetCore.Mvc.Testing),但没有成功。我该如何解决在不同项目中拥有不同Startup.cs的问题,或如何在微服务中进行集成测试。

0 个答案:

没有答案