使用自定义WebApplicationFactory

时间:2019-11-25 13:36:14

标签: c# asp.net-core integration-testing

我正在尝试为asp.net核心Web API设置一个测试项目。我需要处理几个专业:

  1. 使用其他数据库进行测试
  2. 获取UserManger来播种一些用户

根据Documentation,我应该导出WebApplicationFactory的形式并覆盖ConfigureWebHost方法。所以我做到了:

public class CustomWebApplicationFactory : WebApplicationFactory<Startup>
{
    public BeepDbContext Context;
    public UserManager<User> UserMgr;

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            ServiceDescriptor descriptor = services.SingleOrDefault(
                d => d.ServiceType == typeof(DbContextOptions<BeepDbContext>));
            if (descriptor != null) services.Remove(descriptor);

            services.AddDbContext<BeepDbContext>(o =>
                o.UseSqlServer("Server=.\\SQLEXPRESS;Database=BeepTest;Trusted_Connection=true;"));

            ServiceProvider provider = services.BuildServiceProvider();
            using (IServiceScope scope = provider.CreateScope())
            {
                Context = scope.ServiceProvider.GetRequiredService<BeepDbContext>();
                Context.Database.Migrate();

                UserMgr = scope.ServiceProvider.GetRequiredService<UserManager<User>>(); // <--- fails here
            }
        });

    }
}

这是我的测试班:

public class UserControllerTests : IClassFixture<CustomWebApplicationFactory>
{
    private readonly ITestOutputHelper _output;
    private readonly CustomWebApplicationFactory _factory;

    public UserControllerTests(ITestOutputHelper output, CustomWebApplicationFactory factory)
    {
        _output = output;
        _factory = factory;
    }

    [Fact]
    public async Task Login()
    {
        HttpClient client = _factory.CreateClient();

        HttpResponseMessage result = await client.PostAsJsonAsync("/api/auth/login", new UserForLoginDto()
        {
            Username = "user",
            Password = "P@ssw0rd"
        });

        _output.WriteLine(result.StatusCode.ToString());
        _output.WriteLine(result.Content.ReadAsStringAsync().Result);
        Assert.Equal(HttpStatusCode.OK, result.StatusCode);
    }
}

这在我尝试获得UserManager的行上失败,该行说没有为该类型注册的服务。我也无法使它使用测试项目中的配置文件而不是主项目。因此,我对连接字符串进行了硬编码。经过一些调试后,我发现ConfigureServices类中的startup方法是在我重写的方法之后执行的。所以我认为这解释了为什么我无法获得用户管理器。我不明白的是,我做错了什么或如何正确完成?

据我所知,我所做的工作与文档或文档中提供的sample app差不多。

0 个答案:

没有答案