有没有一种方法可以测试结合 TestServer 和 moq Mock 来替换 ConfigureTestServices 中 类 中的方法?
Is there a way to test combining both TestServer and moq Mock to replace methods in classes in ConfigureTestServices?
我可以使用 TestServer 进行集成测试,并且我可以通过将 ConfigureTestServices
中的 class 替换为 class 中注入的任何 DI 中手动模拟方法嘲笑一个如下:
var webHostBuilder =
new WebHostBuilder()
.UseEnvironment("Testing")
.UseContentRoot(projectDir)
.ConfigureTestServices(s =>
{
s.TryAddTransient(IMyClass, MyMockMyClass);
})
.UseStartup<Startup>();
其中MyMockMyClass
是MyClass
的替换,目的是替换一个方法(例如:Method1
)。
是否可以选择使用最小起订量 Mock.Of<MyClass>
快速替换我的 Method1
,而无需创建新的 class MyMockMyClass
?像 :
var mymock = Mock.Of<IMyClass>();
Mock.Get(mymock ).Setup(m => m.Method1(It.IsAny<string>()).Returns(value: whatever);
然后以某种方式将此 mymock
与上面 ConfigureTestServices
代码中的行 s.TryAddTransient(IMyClass, ...
一起使用?
可以使用模拟构建服务集合并将其提供给您的测试服务器,但您不应该这么做。测试服务器用于进行集成测试,而模拟用于单元测试。你需要确定你在做什么样的测试,然后选择一个或另一个。
单元测试,顾名思义,就是测试一个独立的功能单元。模拟是一种删除变量的方法,因此您可以确保您正在测试的东西是否有效。
另一方面,集成测试是自上而下测试系统。您希望确保给定的输入产生给定的输出,使用系统中存在的所有内容。如果你投入模拟,那么你就没有测试任何东西,因为你现在不知道它是否有效,仅仅是因为模拟或实际系统被破坏了。
例如,假设您有一个特定操作使用的服务,该服务存在错误并会导致该操作实时抛出异常。但是,您将其替换为测试服务器中的模拟,效果很好。您的测试通过了,因为模拟正在运行,但是当您将其上线时,一切都崩溃了。相反,您可能无法正确模拟服务,即使实际服务正常,您的测试也可能失败。除非您使用真实系统进行测试,否则您无法保证任何事情。
在配置测试服务器时让工厂委托 return 模拟服务
var mymock = Mock.Of<IMyClass>();
Mock.Get(mymock)
.Setup(m => m.Method1(It.IsAny<string>())
.Returns(value: whatever);
var webHostBuilder =
new WebHostBuilder()
.UseEnvironment("Testing")
.UseContentRoot(projectDir)
.ConfigureTestServices(services => {
services.RemoveAll<IMyClass>();//Remove previous registration(s) of this service
services.TryAddTransient<IMyClass>(sp => mymock);
})
.UseStartup<Startup>();
如果每次调用都需要一个新的模拟实例,则将逻辑移至工厂委托中
我可以使用 TestServer 进行集成测试,并且我可以通过将 ConfigureTestServices
中的 class 替换为 class 中注入的任何 DI 中手动模拟方法嘲笑一个如下:
var webHostBuilder =
new WebHostBuilder()
.UseEnvironment("Testing")
.UseContentRoot(projectDir)
.ConfigureTestServices(s =>
{
s.TryAddTransient(IMyClass, MyMockMyClass);
})
.UseStartup<Startup>();
其中MyMockMyClass
是MyClass
的替换,目的是替换一个方法(例如:Method1
)。
是否可以选择使用最小起订量 Mock.Of<MyClass>
快速替换我的 Method1
,而无需创建新的 class MyMockMyClass
?像 :
var mymock = Mock.Of<IMyClass>();
Mock.Get(mymock ).Setup(m => m.Method1(It.IsAny<string>()).Returns(value: whatever);
然后以某种方式将此 mymock
与上面 ConfigureTestServices
代码中的行 s.TryAddTransient(IMyClass, ...
一起使用?
可以使用模拟构建服务集合并将其提供给您的测试服务器,但您不应该这么做。测试服务器用于进行集成测试,而模拟用于单元测试。你需要确定你在做什么样的测试,然后选择一个或另一个。
单元测试,顾名思义,就是测试一个独立的功能单元。模拟是一种删除变量的方法,因此您可以确保您正在测试的东西是否有效。
另一方面,集成测试是自上而下测试系统。您希望确保给定的输入产生给定的输出,使用系统中存在的所有内容。如果你投入模拟,那么你就没有测试任何东西,因为你现在不知道它是否有效,仅仅是因为模拟或实际系统被破坏了。
例如,假设您有一个特定操作使用的服务,该服务存在错误并会导致该操作实时抛出异常。但是,您将其替换为测试服务器中的模拟,效果很好。您的测试通过了,因为模拟正在运行,但是当您将其上线时,一切都崩溃了。相反,您可能无法正确模拟服务,即使实际服务正常,您的测试也可能失败。除非您使用真实系统进行测试,否则您无法保证任何事情。
在配置测试服务器时让工厂委托 return 模拟服务
var mymock = Mock.Of<IMyClass>();
Mock.Get(mymock)
.Setup(m => m.Method1(It.IsAny<string>())
.Returns(value: whatever);
var webHostBuilder =
new WebHostBuilder()
.UseEnvironment("Testing")
.UseContentRoot(projectDir)
.ConfigureTestServices(services => {
services.RemoveAll<IMyClass>();//Remove previous registration(s) of this service
services.TryAddTransient<IMyClass>(sp => mymock);
})
.UseStartup<Startup>();
如果每次调用都需要一个新的模拟实例,则将逻辑移至工厂委托中