测试开发

《JUnit实战》第7章 使用mock objects进行测试(续3)

7.5 把mocks用作特洛伊木马

mock objects就是特洛伊木马,但是它们并没有恶意。mocks 从内部替代真正的对象,并且调用类并不会意识到这一点。mocks可以访问有关类的内部信息,使得它们更加有用。在当前的示例中,我们仅仅使用它们来模拟真实的行为,但我们并没有挖掘它们能够提供的所有信息。

可以把mocks用作探测器,监视待测试对象所调用的方法。让我们以这个HTTP 连接为例。我们可以监视的一个非常有趣的调用就是Inputstream的close方法。迄今为止我们没有对 Inputstream使用一个mock object,但是我们可以很容易地创建一个,并且提供一个 verify方法来确认 close已经被调用。然后我们可以在测试的最后调用verify方法来验证所有应该调用的方法是否都已经被调用了(如代码7.13所示)。我们可能也会想要验证close是否只被调用了一次,如果它被调用多次或者根本没有被调用,那么就抛出异常。这些验证通常被称为预期(expectation)。

DEFINITION 预期( expectation)——当我们谈论mock objects 的时候,预期就是内嵌在mock

里面的一个特性,用来验证调用此mock的外部类是否具有正确的行为。例如,一个数据库连接mock能够验证,在任何使用该mock的测试中,这个连接中的close方法都被调用了一次。

代码7.13中展示了一个关于预期((expectation)的示例。

image.png

image.png

在 MockInputstream类中,close的预期很简单:我们希望它总是被调用一次。但是在大多数情况下,closecount的预期都依赖于待测试代码。一个mock 通常会有一个类似setExpected-Closecalls的方法,这样测试就可以告诉mock预期会发生什么。

接下来让我们修改TestWebclient.testGetcontentok的测试方法,以便使用新的MockInputStream:

image.png

在之前的测试中使用的是真正的ByteArrayInputstream,而现在我们使用的是MockInputStream。请注意,我们在测试的结尾处调用了MockInputStream 的验证方法,以确认是否满足了我们所有的预期。运行测试的结果如图7.4所示。

这个测试会失败并弹出消息“close () should have been called once and once only"。这是为什么?因为我们没有关闭webclient.getContent方法中的输人流。如果我们关闭了两次或者更多次,同样的问题还是会出现,这是因为测试检查的是被调用一次并且仅仅一次。

让我们修改一下待测试代码(参见代码7.14)。

image.png

图7.4 在新的close预期下运行 TestWebClient

image.png

现在我们就可以看到漂亮的绿色进度条了,如图7.5所示。

对于预期,还有一些其他简单方便的用法。例如,假如你有一个组件管理器,在组件生命周期内调用不同的方法,那么你可能会预期这些方法是按照一定的顺序被调用的。或者,你可能会期望某个指定的值作为参数传递给mock。一般可以认为,除了能够在测试中提供你想要的行为,mock同样可以就其使用情况提供有用的反馈。

image.png

图7.5  运行的 WebClient关闭了输入流

下一章节将会展示使用一些最流行的开源mock框架的使用——它们功能强大,完全能够满足我们的需求,并且我们不需要从一开始就实现mock。

相关内容

文章评论

表情

共 0 条评论,查看全部
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~