繁体   English   中英

Moq是否取代标准的VS'Assert'测试?

[英]Does Moq replace standard VS 'Assert' testing?

我试图了解如何使用Moq,但是我对Moq应该用于什么感到困惑。 我的理解是,模拟框架用于生成在正常情况下难以创建的对象。 我看过Moq的例子似乎不仅创建了Moq对象,而且还提供了测试对象的方法 - 这似乎消除了我们用于大多数单元测试的常用Assert等方法的需要。

有人可以确认我是否认为Moq取代Assert等是正确的,还是我完全忽略了Moq的观点?

像Moq这样的模拟框架并没有完全取代测试框架的Assert 有时它确实如此,有时却没有。

让我们首先区分嘲笑和存根。 存根纯粹用于隔离并将某种受控行为注入被测系统(SUT)。

模拟是存根的超集,能够验证是否在模拟上调用了某些内容。 在Moq中,调用Verify()会使stub成为关于该方法的模拟。 调用VerifyAll()会使所有设置的方法都被VerifyAll()

建议的方法是在测试中应该只有一个模拟。 从这个意义上讲,它类似于Assert - 你不应该在测试中验证多个东西。

回到最初的问题。 如果您正在执行状态测试,那么您将使用零个或多个存根和一个断言。 如果您正在进行交互测试,那么您将使用零个或多个存根和一个模拟。 下面是一个示例,其中可能适合使用mocks和asserts来测试相同的服务。

public interface IAccountRepository {
  decimal GetBalance(int accountId);
  void SetBalance(int accountId, decimal funds);
}

public class DepositTransaction {

  IAccountRepository m_repo;

  public DepositTransaction(IAccountRepository repo) {
    m_repo = repo;
  }

  public decimal DepositedFunds {get; private set;};

  void Deposit(int accountId, decimal funds) {
    decimal balance = m_repo.GetBalance(accountId);
    balance += funds;
    m_repo.SetBalance(balance);

    DepositedFunds += funds;
  }
}

public class DepositTest {
  [TestMethod]
  void DepositShouldSetBalance() {
    var accountMock = new Mock<IAccountRepository>();
    accountMock.Setup(a=>a.GetBalance(1)).Returns(100); //this is a stub with respect to GetBalance

    var transation = new DepositTransaction(accountMock.Object);
    transation.Deposit(1, 20);

    accountMock.Verify(a=>a.SetBalance(1, 120)); //this is a mock with respect to SetBalance
  }
  [TestMethod]
  void DepositShouldIncrementDepositedFunds() {
    var accountMock = new Mock<IAccountRepository>();
    accountMock.Setup(a=>a.GetBalance(1)).Returns(100); //this is a stub with respect to GetBalance

    var transation = new DepositTransaction(accountMock.Object);
    transation.Deposit(1, 20);
    transation.Deposit(1, 30);

    Assert.AreEqual(50, transaction.DepositedFunds);

  }
}

Q上的+1和其他A ......

(重述Igor非常完整的答案)Mocking库只是测试/规范中的工具使用 - 有时候会完成存根或模拟的角色。

基于记录/重放的模拟通常可以在测试中替换Assert的角色。 这种风格最近在RhinoMocks中被忽略了(我相信4.0会将它分流到一边),并且在Moq中已经积极劝阻了很长一段时间。 我相信这就是你问这个问题的原因。

您应该优化您的测试:

  • 对于您,维护程序员以及几乎任何需要调试或从测试代码中提取信息的人来说都是可读的
  • 断言尽可能少
  • 与其他测试不重叠
  • 不易碎 - 当你改变与你的测试相关的东西时,测试不应该因为偶然的原因而破坏。 在莫青和嘲讽的背景下,这意味着在大多数情况下都要偏离严格的嘲笑
  • 做尽可能少的工作来证明他们的观点
  • 清楚地分离Arrange / Context,Act和Assert部分

这里的最后一点是关键点 - 你想要一点你正在做Checks,它应该是最后的断言。 有时这可能意味着您甚至可以在排列/上下文阶段最终在Moq中进行Setup调用,然后验证它是否在Assert阶段使用,代码看起来像重复。

暂无
暂无

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

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