unit-testing - 测试: stub vs real implementation

标签 unit-testing testing tdd integration-testing

我一直想知道单元测试中 stub 的一般用途与使用真实(生产)实现的情况,特别是在使用 stub 时我们是否不会遇到相当讨厌的问题,如下所示:

假设我们有这个(伪)代码:

public class A {
  public int getInt() {
    if (..) {
      return 2;
    }
    else {
      throw new AException();
    }
  }
}

public class B {
  public void doSomething() {
    A a = new A();
    try {
      a.getInt();
    }
    catch(AException e) {
      throw new BException(e);
    }
  }
}


public class UnitTestB {
  @Test
  public void throwsBExceptionWhenFailsToReadInt() {
     // Stub A to throw AException() when getInt is called
     // verify that we get a BException on doSomething()
  }
}

现在假设我们在稍后的某个时刻,当我们编写了数百个测试时,意识到 A 不应该真正抛出 AException,而应该抛出 AotherException。我们纠正这个问题:

public class A {
  public int getInt() {
    if (..) {
      return 2;
    }
    else {
      throw new AOtherException();
    }
  }
}

我们现在已经更改了 A 的实现以抛出 AotherException,然后运行所有测试。他们通过了。不太好的情况是 B 的单元测试通过了,但是是错误的。如果我们在这个阶段将 A 和 B 放在生产中,B 将传播 AotherException,因为它的实现认为 A 抛出 AException。

如果我们在 throwsBExceptionWhenFailsToReadInt 测试中使用 A 的实际实现,那么在 A 更改后它就会失败,因为 B 不会再抛出 BException。

这只是一个可怕的想法,如果我们有数千个像上面的例子一样构造的测试,并且我们改变了一件小事,那么所有的单元测试仍然会运行,即使许多单元的行为是错误的!我可能遗漏了一些东西,我希望你们中的一些聪明人能够启发我它是什么。

最佳答案

当你说

We have now changed the implementation of A to throw AOtherException and we then run all our tests. They pass.

我认为这是不正确的。显然你还没有实现你的单元测试,但是B类不会捕获AException,因此不会抛出BException,因为AException现在是AotherException。也许我遗漏了一些东西,但是您的单元测试不会在断言此时抛出 BException 时失败吗?您将需要更新类代码以正确处理 AotherException 的异常类型。

关于unit-testing - 测试: stub vs real implementation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9708730/

相关文章:

java - JTAPI API 有模拟器吗?

windows - 将 Windows 笔记本电脑变成 iBeacon

仅当所有测试通过时 Git 主存储库更新,怎么办?

python - 用于浮点集合的 Python 单元测试中的 assertAlmostEqual

python - Django - 测试页面的 500 状态

wcf - 如何使用 Moq 模拟 WCF 客户端?

unit-testing - 为什么要使用测试驱动开发?

ios - 如何使用 protected init 来模拟对象

unit-testing - 由外向内 TDD : Should I check in failing acceptance tests?

django - 如何开始在 django 项目中进行 TDD?