我有一个使用自定义
CustomWebApplicationFactory
的方法来调用
services.AddHangfire(configure => configure.UseInMemoryStorage()).AddHangfireServer(configuration =>
{
configuration.WorkerCount = 1;
configuration.Queues = new[] {"critical", "default" };
});
然后在方法本身中,我调用
WithWebHostBuilder
来动态更改用于集成测试的连接字符串。
接下来是我的作业存储始终包含 0 个作业。调用
JobStorage.Current
或 factory.Services.GetRequiredService<JobStorage>()
会在同一个空存储中产生结果,而如果我删除 WithWebHostBuilder
调用并跳过创建第二个 WebHost,则测试时一切都会按预期工作 - 两个调用都指向包含我的作业的存储。已运行集成测试。
这两种情况都会执行有问题的作业,所以我猜测由于
WithWebHostBuilder
执行其操作的性质,实际上有 2 个内存中的hangfire 方法/服务器注册,因此,第一个服务器承担负载,我只剩下一个空的存储空间。
这是怎么回事?如果是这样,除了为我正在测试的
EVERY连接字符串创建一个包含自定义
WebApplicationFactory
实例的自定义夹具之外,我该如何解决该问题?这将需要大量的重构,因为这样我就不能使用内联数据,并且我必须创建一个可以与单个此类实例一起使用的内部方法,否则我必须为每个实例重复我的集成测试.
我很想避免上述情况!
要尝试的三件事:
我认为您可能同时创建原始 WebApplicationFactory 和新 WebApplicationFactory?
builder.ConfigureServices(services => {
services.RemoveAll(typeof(GlobalConfiguration));
services.AddHangfire(config => config
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseMemoryStorage());
});
如果您在 Program.cs 中有 Local、Development、QA、Production 的设置,请确保运行正确的环境变量 WebApplicationFactory 的默认值为“Development”。
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Local"); // Default setting is to use Development environment
base.ConfigureWebHost(builder);
builder.ConfigureServices(services => {
services.RemoveAll(typeof(GlobalConfiguration));
services.AddHangfire(config => config
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseMemoryStorage());
});
}
记录和测试
此外,您可以在 Program.cs 中放置断点,然后在运行单元/集成测试时选择“调试测试”来逐步执行代码。然后,您可以看到 WebApplicationFactory 正在修改哪些内容,哪些内容保持正常,哪些地方出现问题。
还在 builder.ConfigureTestServices() 中添加日志记录
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Local");
base.ConfigureWebHost(builder);
builder.ConfigureServices(services => {
services.RemoveAll(typeof(GlobalConfiguration));
services.AddHangfire(config => config
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseMemoryStorage());
});
builder.ConfigureTestServices(services =>
{
// Put mocks here
//services.AddSingleton(your_mocks);
services.AddLogging(builder => builder.AddConsole().AddDebug()); // Any issues, check the output window to see where the build is failing.
});
}