使用 Moq 确定是否调用了方法

我的理解是,如果我调用一个更高级别的方法,我可以测试一个方法调用是否会发生,比如:

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


internal abstract void SomeOtherMethod();
}

我想测试,如果我调用 SomeMethod(),那么我希望 SomeOtherMethod()将被调用。

我认为这种类型的测试在一个模仿框架中是可用的,这种想法对吗?

93051 次浏览

您可以通过使用 Verify 查看是否已经调用了您模仿的某个方法,例如:

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

如果该行留有注释,则在调用 Verify 时将抛出一个 MockException。如果取消注释,它将通过。

不,模拟测试假设您正在使用某些可测试的设计模式,其中之一就是注入。在您的情况下,您将测试 SomeClass.SomeMethodSomeOtherMethod必须实现在另一个实体,需要接口。

您的 Someclass构造函数应该类似于 New(ISomeOtherClass)。然后您将模拟 ISomeOtherClass,并在其 SomeOtherMethod上设置期望值,以便调用并验证期望值。

即使我同意的 @ Paul 的回答是推荐的方式去,我只是想增加一个替代方式,是由 moq提供了自我。

因为 SomeClassabstract,所以它确实是可模仿的,但是 public void SomeMehod()不是。关键是要找到模拟的方法,并以某种方式调用该方法,然后使用 CallBase传播对 SomeOtherMethod()的调用。这可能听起来像黑客行为,但本质上很简单。如果所提议的重构不可能,则可以在此情况下使用它。

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

然后,可以通过设置 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);