1

不要过度依赖于 Mocks!

 2 years ago
source link: https://www.continuousdelivery20.com/blog/tott-dont-overuse-mocks/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
不要过度依赖于 Mocks!

乔梁 | 2021-04-15

在为代码编写测试时,通过对代码的依赖关系进行 Mock ,让测试写起来似乎更容易。

然而,过度使用 Mocks 可能带来几个问题:

  • 让测试代码更难以理解。与直接使用代码(例如,将一些值传递给被测试的方法并检查返回结果)不同,你需要写一些额外的代码来告诉 mock 如何工作。而这些额外的代码会影响你要测试的内容的实际意图。如果你不熟悉生产代码的这些实现,通常就很难理解这些测试代码。

  • 测试用例更难为维护。 当你告诉一个 Mock 如何返回你期望的数据时,你是将代码的实现细节泄漏到了测试用例中。当产品代码中的实现细节发生变更时,您还需要修复相应的测试用例中的 Mock ,才能真实反映这些变更。测试通常应该对代码的实现知之甚少,而应该专注于验证生产代码的公共接口。

  • 测试用例无法保证代码能正常工作。当你告诉一个 Mock 如何返回你期望的数据时,你在测试中得到的唯一保证是:如果您的 Mock 的行为与实际实现完全相同,那么您的代码将正常工作。然而,这可能很难完全保证。而且,随着时间的推移和代码的变化,问题会变得更糟,因为实际上真实的代码行为很可能与你的 Mock 并不同步。

例如下面的例子。

public void testCreditCardIsCharged() {
  paymentProcessor = new PaymentProcessor(mockCreditCardServer);
  when(mockCreditCardServer.isServerAvailable()).thenReturn(true);
  when(mockCreditCardServer.beginTransaction()).thenReturn(mockTransactionManager);
  when(mockTransactionManager.getTransaction()).thenReturn(transaction);
  when(mockCreditCardServer.pay(transaction, creditCard, 500)).thenReturn(mockPayment);
  when(mockPayment.isOverMaxBalance()).thenReturn(false);
  paymentProcessor.processPayment(creditCard, Money.dollars(500));
  verify(mockCreditCardServer).pay(transaction, creditCard, 500);
}

然而,不使用 Mocks ,有时会让测试用例更简单,也更有效。

public void testCreditCardIsCharged() {
  paymentProcessor = new PaymentProcessor(creditCardServer);
  paymentProcessor.processPayment(creditCard, Money.dollars(500));
  assertEquals(500, creditCardServer.getMostRecentCharge(creditCard));
}

有一些迹象会显示你可能过度使用 Mock 了。例如,

  • 你模拟了多个类,或者其中的一个 Mock 指定了两个及以上方法的行为方式。

  • 当你在阅读一个使用了 Mock 的测试用例时,发现自己为了理解它而不得不去理解被测试的代码。

有时,你无法在测试用例中使用真实的依赖项(例如,依赖项本身运行速度太慢,或者需要网络会话)。然而,你仍旧有可能会有比 Mock 技术更好的选择。比如使用封闭服务器(例如,在你自己的机器上专门为测试启动的一个信用卡服务器)或者一个 伪实现( Fake implementation,比如建立在内存中的信用卡服务器)。

关于更多关于密闭服务器的信息,请参见《 使用密闭服务(Hermetic Servers)进行测试》。


原文作者:Andrew Trenk

原文链接:Don’t Overuse Mocks

发表时间:May 28, 2013


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK