【问题标题】:Moq testing if method1 calls second method2 in same class最小起订量测试方法 1 是否调用同一类中的第二个方法 2
【发布时间】:2018-11-11 09:22:02
【问题描述】:

我是 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
  }
}

我认为我可以这样编写单元测试:

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

  aMock.TestMethod();

  aMock.VerifyAll();
}

但这有效吗?谢谢大家的好回答!

【问题讨论】:

标签: c# unit-testing moq


【解决方案1】:

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

对非虚拟成员的验证无效:m => 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 调用,即将Verify 移动到调用 .TestMethod() 之后,就像我所做的那样。李>
  • 虽然您可以更改代码以使用Setup + VerifyAll 方法进行测试,即确保实际调用您设置的所有内容:

aMock.Setup(m => m.TestMethod2());

aMock.Object.TestMethod();

aMock.VerifyAll();

然而,关于VerifyAll 的使用是否违反AAA 原则存在争议(因为您实际上也在Arrange 部分中指定了Verify 标准),我还发现这方法使得在大规模测试中无法重构和干燥 Mock 设置,并且您还失去了一些更精细的检查级别(例如 Times.Once)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 1970-01-01
    • 2022-04-01
    相关资源
    最近更新 更多