简体   繁体   English

不能在单元测试中使用模拟接口 class

[英]Can't use a mocked Interface class in Unit Test

I'm trying to mock a method in my Unit Test but I can't debug into the the method from the service.我试图在我的单元测试中模拟一个方法,但我无法从服务中调试到该方法。

I have a service with the method DoSomething1 that I want to test:我有一个要测试的方法 DoSomething1 的服务:

public MyService : IMyService
{
    private IAnotherService _anotherService;

    public MyService(IAnotherService anotherService)
    {
        _anotherService = anotherService;
    }

    public async Task DoSomething1(string param)
    {
        // Code...
        _anotherService.DoSomething2(string param1, string param2);
        // Code...
    }
}

This is my testing class:这是我的测试 class:

[TestClass]
public class MyServiceTests : TestBase
{
    private Mock<IAnotherService> _mockAnotherService;
    
    [TestInitialize]
    public void Setup()
    {
        _mockAnotherService = new Mock<IAnotherService>();
    }

    [TestMethod]
    public async Task Test_MyService_DoSomething()
    {
        var myService = new MyService(_mockAnotherService.Object);

        var result = myService.DoSomething1(param1);

        // Some Asserts...
    }
}

If I now debug it I can get into MyService but I can't debug into如果我现在调试它,我可以进入 MyService 但我无法调试

_anotherService.DoSomething2(string param1, string param2);

And it will fail my tests.它会通过我的测试。

Using this works but seems to be bad practice:使用这个工作,但似乎是不好的做法:

var myService = Container.GetInstance<MyService>();

What am I missing?我错过了什么?

The purpose of a mock is to be a stand-in for the real thing.模拟的目的是成为真实事物的替身。 In testing scenarios it is often undesirable to have the whole object graph wired up, because it is often hard to set up, parts of it might interact with resources that are not available/slow/unreliable, or it might make it much harder, if not impossible to invoke certain edge cases or error scenarios.在测试场景中,通常不希望将整个 object 图连接起来,因为它通常很难设置,其中的一部分可能与不可用/缓慢/不可靠的资源交互,或者它可能会使它变得更加困难,如果调用某些边缘情况或错误场景并非不可能。

In a comment you state that using Container.GetInstance<MyService>() instead of setting it up with a mock is passing your tests.在评论中,您 state 使用Container.GetInstance<MyService>()而不是使用模拟设置它正在通过您的测试。 This means you are using the real implementation of IAnotherService .这意味着您正在使用IAnotherService的实际实现。 If this is not posing any problems then do that.如果这没有造成任何问题,那么就这样做。 If you are unable to invoke certain test cases with "the real thing" or it turns out that your tests become brittle or slow, then mock it.如果您无法使用“真实的东西”调用某些测试用例,或者您的测试变得脆弱或缓慢,那么请模拟它。

If you use a mock of IAnotherService then the instance of it is not going to do anything by itself.如果您使用IAnotherService的模拟,那么它的实例本身不会做任何事情。 You can tell the mock to return something, but that is pretty much it.您可以告诉模拟返回一些东西,但仅此而已。 eg例如

_mockAnotherService.Setup(m => m.DoSomething2("a", "b")).Returns(42);

The mock wont be able to simulate any side effects (ie writing to a DB or file).模拟将无法模拟任何副作用(即写入数据库或文件)。 You have to simulate that directly in your test.您必须直接在测试中进行模拟。 Debugging into the mocked version of DoSomething2() , if it were possible for you, would only show you how the Moq is implementing its mocks.如果可能的话,调试到DoSomething2()的模拟版本只会向您展示 Moq 是如何实现其模拟的。 Assume that they are doing the right thing and that it makes no sense to debug.假设他们正在做正确的事情并且调试没有意义。 It is not the real DoSomething2() .它不是真正的DoSomething2()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM