简体   繁体   English

使用Moq确定是否调用方法

[英]Using Moq to determine if a method is called

It is my understanding that I can test that a method call will occur if I call a higher level method, ie: 据我了解,如果我调用更高级别的方法,则可以测试是否将发生方法调用,即:

public abstract class SomeClass()
{    
    public void SomeMehod()
    {
        SomeOtherMethod();
    }

    internal abstract void SomeOtherMethod();
}

I want to test that if I call SomeMethod() then I expect that SomeOtherMethod() will be called. 我想测试一下,如果我调用SomeMethod()那么我希望将调用SomeOtherMethod()

Am I right in thinking this sort of test is available in a mocking framework? 我认为这种测试可以在模拟框架中使用对吗?

You can see if a method in something you have mocked has been called by using Verify, eg: 您可以查看是否已经通过使用验证调用了您模拟的方法,例如:

static void Main(string[] args)
{
        Mock<ITest> mock = new Mock<ITest>();

        ClassBeingTested testedClass = new ClassBeingTested();
        testedClass.WorkMethod(mock.Object);

        mock.Verify(m => m.MethodToCheckIfCalled());
}

class ClassBeingTested
{
    public void WorkMethod(ITest test)
    {
        //test.MethodToCheckIfCalled();
    }
}

public interface ITest
{
    void MethodToCheckIfCalled();
}

If the line is left commented it will throw a MockException when you call Verify. 如果对行进行注释,则在调用Verify时将抛出MockException。 If it is uncommented it will pass. 如果未注释,它将通过。

No, mock testing assumes you are using certain testable design patterns, one of which is injection. 不,模拟测试假定您正在使用某些可测试的设计模式,其中之一就是注入。 In your case you would be testing SomeClass.SomeMethod and SomeOtherMethod must be implemented in another entity which needs to be interfaced. 在您的情况下,您将测试SomeClass.SomeMethodSomeOtherMethod必须在另一个需要接口的实体中实现。

Your Someclass constructor would look like New(ISomeOtherClass) . 您的Someclass构造函数看起来像New(ISomeOtherClass) Then you would mock the ISomeOtherClass and set expectation on its SomeOtherMethod to be called and verify the expectation. 然后,您将模拟ISomeOtherClass并在要调用的SomeOtherMethod上设置期望值并验证期望值。

Even though I agree that the @Paul's answer is the recommended way to go I just want to add one alternative way which is provided by moq off the self. 即使我同意@Paul的答案是推荐的解决方法,但我只想添加一种由moq off self提供的替代方法。

Since SomeClass is abstract it is indeed mockable, but public void SomeMehod() isn't. 由于SomeClassabstract因此它确实是可模拟的,但public void SomeMehod()却不是。 The point is to find the way to mock and somehow invoke that method and then using CallBase propagate the call to the SomeOtherMethod() . 关键是找到模拟方法并以某种方式调用该方法,然后使用CallBase将调用传播到SomeOtherMethod() It might sound as a hack but it is simple in essence. 听起来可能很hack,但本质上很简单。 It could be used in the case if the proposed refactoring is not possible. 如果无法进行建议的重构,则可以使用它。

// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
    public virtual void DummyMethod() => base.SomeMethod();
}

Then you could setup DummyMethod() to propagate the call by setting CallBase flag. 然后,您可以通过设置CallBase标志来设置DummyMethod()以传播呼叫。

//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();

//Act
mock.Object.SomeMethod();

//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);

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

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