如果method1在同一个类中调用第二个method2,则测试Moq

时间:2018-06-01 09:12:25

标签: c# unit-testing moq

我是Moq的新手

我阅读了很多关于Moq测试的内容,并且你不应该测试你的模拟对象,而是应该使用Moq来存储依赖项并使其按照你想要的方式运行。但是现在我问自己,你如何测试一个方法是否可以从同一个类中的另一个方法调用,如下代码:

public class A // --> class i want to test
{
  public virtual void TestMethod() // --> does it call testmethod2
  {
    TestMethod2();
  }

  public virtual void TestMethod2()
  {
    // Do something
  }
}

我以为我可以像这样编写Unittest:

[TestMethod]
public void MyTestMethod()
{
  Mock<A> aMock = new Mock<A>();
  aMock.Verify(o => o.TestMethod2(), Times.Once);

  aMock.TestMethod();

  aMock.VerifyAll();
}

但这有效吗?谢谢你们所有的好答案!

1 个答案:

答案 0 :(得分:0)

Moq只能模拟虚拟方法(或提供接口的模拟实现)。如果您在非虚拟成员上尝试SetupVerify,则会收到错误

  

非虚拟成员的验证无效:m =&gt; m.TestMethod2()

在您的情况下,您需要将TestMethod2更改为虚拟,即

public virtual void TestMethod2()

然后可以测试:

var aMock = new Mock<A>();

aMock.Object.TestMethod();

aMock.Verify(m => m.TestMethod2(), Times.Once);

正如你所建议的那样,测试一个类是否称为内部自身的方法是一种气味,表明你是

  • 测试内部实施细节(例如TestMethod2()是私有的,我们的业务甚至都不知道)。
  • 或者,表明被测试的类/系统需要重构为多个类,这些类应该是松散耦合的,因此可以被隔离并且更易于测试。

注意

  • 在您调用要测试的SUT上的方法之前,您无法Verify进行调用,即在调用{{1}之后移动Verify我已经完成了。
  • 虽然您可以更改代码以使用.TestMethod() + Setup方法进行测试,即确保实际调用您设置的所有内容:

VerifyAll

然而,关于aMock.Setup(m => m.TestMethod2()); aMock.Object.TestMethod(); aMock.VerifyAll(); 的使用是否违反VerifyAll委托人(因为您还有效指定AAA条中的Verify条件,存在争议),我也发现这种方法使得在大规模测试中无法重构和干掉Mock设置,并且你也失去了一些更精细的检查(例如Arrange)。