首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确地为void编写TDD?

如何正确地为void编写TDD?
EN

Software Engineering用户
提问于 2014-08-17 20:49:27
回答 1查看 672关注 0票数 5

好的,我的场景是:我有一个第三方组件,它提供了一个API来与外部系统通信。该方法要求命令外部系统进行操作,全部返回无效。

因此,我所做的就是创建了一个包装器接口,并模拟了外部系统。但是,由于我的代码中没有调用外部API上的内容的真正逻辑或检查,所以代码只是过程性的。除了调用这些方法之外,我无法真正测试其他任何东西。

代码语言:javascript
复制
_systemWrapper.DoStuff(a, b ,c , d);
_systemWrapper.DoStuff2(e, f);
_systemWrapper.DoStuff3(g);

我无法通过测试配置外部系统,因此集成测试是不可能的。

因此,为了测试这个问题,我已经模拟出了我的"_systemWrapper“,并且正在验证我在模拟中调用的参数是否包含正确的参数。这是解决这个特殊问题的一种常见方法吗?在我看来,有一个测试来确保您有这个和这一行代码是有点详尽的。

问题是,这个系统变得越来越大,并且编写断言这个和这一行存在的测试已经失去控制,重构变得非常困难,如果我们改变对第三方的调用,那么所有的测试都会失败。

EN

回答 1

Software Engineering用户

回答已采纳

发布于 2014-08-17 22:58:43

有许多处理外部apis问题的技术。我将尝试描述几种可能有用的方法。

模拟

在这里,您的测试断言执行了特定的调用序列。这是你尝试过的技术,你发现了它的下落。当外部api非常简单时,它工作得很好。然而,对于复杂的apis,它通常会成为问题。这些测试很脆弱,甚至不能很好地解决真正的问题。

你可以通过放松你的测试来帮助这些测试的脆性。您通常不需要断言测试生成的函数调用的确切顺序。也许你的测试能让更多的李路。

实际实现

在许多情况下,理想的解决方案是根据api的实际实现进行实际测试。这样,您就可以断言想要发生的事情实际上正在发生,而不必担心传递给API的确切参数。正如您注意到的,“我无法通过测试配置外部系统,因此集成测试是不可能的。”所以这看起来可能对你不管用。

但是,取决于为什么不能在测试中配置外部系统,可能仍然有一种方法来使用它。一种可能是设置测试,以便它们可以在两种模式下运行。在第一种模式中,它们实际上是针对外部系统运行的,并验证是否发生了正确的事情。但是,它们也记录了所进行的api调用的顺序。在第二个过程中,您只需验证是否执行了相同的调用序列。

在正常开发期间,您只需在第二种模式下运行测试,假设您通常不需要修改所进行的调用。但是,在重构代码和更改调用的情况下,您将重新运行针对外部api的测试,并重新获得调用的顺序。然后,您可以继续编写代码,让测试维护新的序列。

记录序列

另一种可能是,又有两种模式。在记录模式中,记录对外部api的调用顺序。在验证模式中,您验证仍在进行相同的调用。通常,您使用验证模式。但是,无论何时您确实需要更改调用序列,都可以在记录模式下重新运行测试,以捕获新的调用序列。然后,您可以查看新旧序列之间的差异,以验证该序列是否仍然有意义。

使用假

您可以实现一个假的,而不是一个模拟。不同之处在于,假的行为类似于外部api。它对外部api进行建模,维护类似的内部状态和/或产生相同的结果。与其验证是否进行了正确的调用,不如验证该假是否已进入正确状态或提供了相同的结果。它可以验证有关api调用方允许做什么的任意数量的规则。例如,如果在调用"baz“方法之前不能调用"foobar”方法,则fake可以抛出异常。

假货是非常好的和灵活的,但确实需要时间来实施。有时候,你可以在现有的库/解决方案的基础上即兴创作一个假的。例如,可以通过使用嵌入式数据库(如H2H2 )来伪造“真实的”SQL数据库。

避免Api

您可以尝试构造您的程序,以便尽可能少地实际与外部api交互。这可能需要一些聪明的思考。通常,您可以将直接与有问题的api交互的程序数量减少到一个小部分。

票数 8
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/253608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档