有没有一种方法可以测试结合TestServer和moq Mock以替换ConfigureTestServices中的类中的方法?

时间:2019-01-11 13:51:27

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

我能够使用TestServer进行集成测试,并且可以通过模拟以下方法ConfigureTestServices替换类,从而手动模拟任何注入DI的类中的方法:

var webHostBuilder =
    new WebHostBuilder()
        .UseEnvironment("Testing")
        .UseContentRoot(projectDir)
        .ConfigureTestServices(s =>
        {
            s.TryAddTransient(IMyClass, MyMockMyClass);
        })
        .UseStartup<Startup>();

MyMockMyClassMyClass的替换,目的是替换方法(例如:Method1)。

是否可以使用最小订量Mock.Of<MyClass>快速替换我的Method1,而无需创建新的类MyMockMyClass?像这样:

var mymock = Mock.Of<IMyClass>();
Mock.Get(mymock ).Setup(m => m.Method1(It.IsAny<string>()).Returns(value: whatever);

然后以某种方式在上面的mymock代码中将此s.TryAddTransient(IMyClass, ...与行ConfigureTestServices一起使用?

2 个答案:

答案 0 :(得分:1)

在配置测试服务器时让工厂代表返回模拟服务

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

如果每个调用需要一个新的模拟实例,则将逻辑移至工厂委托中

答案 1 :(得分:0)

可以使用模拟建立服务集合并将其提供给测试服务器,但您不应这样做。测试服务器用于进行集成测试,而模拟用于单元测试。您需要确定要进行哪种测试,然后选择其中一种。

顾名思义,

单元测试与测试功能的一个离散单元有关。模仿是一种删除变量的方法,因此您可以确保所测试的某件事是否起作用。

另一方面,集成测试是自上而下地测试系统。您要确保给定的输入产生给定的输出,使用系统中存在的所有内容。如果您加入了模拟程序,那么您就不会进行任何测试,因为您现在不仅仅因为模拟程序或实际系统已损坏而无法知道它是否有效。

例如,假设您有一个特定操作使用的服务,该服务有一个错误,将导致该操作实时抛出异常。但是,您可以在测试服务器中将其替换为模拟,这可以正常工作。您的测试通过了,因为该模拟正在运行,但是当您将其实时发布时,一切都会中断。相反,您可能无法正确模拟服务,即使实际服务正常,测试也可能失败。除非您在实际系统上进行测试,否则您将无法保证任何事情。