Web 应用程序工厂在 MVC 测试框架中共享测试特定设置?
在使用 MVC.Testing 包中的 WebApplicationFactory 进行集成测试时,我遇到了一个奇怪的问题。 在一个测试中,我创建工厂并使用ConfigureTestServices 函数将注入的服务交换为另一个模拟服务,在另一个测试中我没有这样做。但是,我发现每个测试最终都可以使用相同的模拟实现。
// 测试 1
var mock = new Mock<SomeService>();
mock.Setup(t => t.ProcessJob(It.IsAny<SomeService>()))
.Throws(new Exception("Exception thrown in unit test"));
var factory = new WebApplicationFactory<Program>()
.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(SomeService));
if (descriptor != null)
services.Remove(descriptor);
services.AddScoped<SomeService>(_ => mock.Object);
});
});
var client = factory.CreateClient();
var message = BuildMessage();
var response = await client.SendAsync(message);
//测试 2
var factory = new WebApplicationFactory<Program>();
var client = factory.CreateClient();
var message = BuildMessage();
var response = await client.SendAsync(message);
我跳过了断言,因为它们与此无关。
因此,在此示例中,Test2 最终使用与 Test1 相同的模拟“SomeService”对象,即使它从未在该实例中实现。测试的顺序并不重要,因为如果先运行 Test1,则 Test2 将失败;如果先运行 Test2,则 Test1 将失败。
我很困惑为什么会发生这种情况。他们应该使用完全独立的容器,因此完全隔离。
任何想法都会受到欢迎。
编辑: 一些进一步的调查表明,队列仍在后台运行,因为 WebApplicationFactory 似乎没有在测试结束时立即释放。在测试结束时调用 .Dispose 会导致队列抛出“无法访问已处置对象”异常。
WebApplicationFactory 中是否有一种方法可以等到所有内容都正确处理后再结束测试?
I'm having a strange issue when using the WebApplicationFactory in the MVC.Testing package for integration testing.
In one test, I'm creating the factory and swapping an injected service for another mocked service using the ConfigureTestServices function, in the other test I'm not doing this. However, I'm finding that each test can end up using the same mock implementation.
// Test 1
var mock = new Mock<SomeService>();
mock.Setup(t => t.ProcessJob(It.IsAny<SomeService>()))
.Throws(new Exception("Exception thrown in unit test"));
var factory = new WebApplicationFactory<Program>()
.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(SomeService));
if (descriptor != null)
services.Remove(descriptor);
services.AddScoped<SomeService>(_ => mock.Object);
});
});
var client = factory.CreateClient();
var message = BuildMessage();
var response = await client.SendAsync(message);
//Test 2
var factory = new WebApplicationFactory<Program>();
var client = factory.CreateClient();
var message = BuildMessage();
var response = await client.SendAsync(message);
I've skipped the assertions as they're irrelevant for this.
So in this example, Test2 ends up using the same mocked "SomeService" object as Test1 does, even though it's never implemented in that instance. The ordering of the test doesn't matter in the sense that Test2 will fail if Test1 runs first and Test1 will fail if Test2 runs first.
I'm confused as to why this would happen. They should be using completely separate containers and therefore be completely isolated.
Any thoughts would be welcome.
EDIT:
Some further investigation shows that a queue is still running in the background as the WebApplicationFactory doesn't seem to get disposed immediately at the end of the tests. Calling .Dispose at the end of the test causes the queue to throw a "can't access disposed object" exception.
Is there a method within the WebApplicationFactory to wait until everything is correctly disposed before ending the test?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论