gpt4 book ai didi

使用 DAO 测试对象

转载 作者:行者123 更新时间:2023-11-28 20:25:31 25 4
gpt4 key购买 nike

继续另一个关于测试的类似问题(see here)。我将使用类似的示例(伪代码)

class LinkDisplayer
method constructor(LinkStorage)
method displayLatestLinksByCategory(number_of_them)

class LinkStorage
method saveLink(Link)
method retrieveLatestLinksByCategory(category, number_of_them)

class Link
method getUrl()
method getDescription()
method getCategory()

所以 linkDisplayer 使用 LinkStorage 来获取链接。我要测试的行为是“shouldDisplayLatestLinks”。在我的测试中,我是否需要模拟 LinkStorage,并让它返回具有模拟 getUrl() 等行为的模拟链接对象?

测试“叶”类很容易,但我仍然发现很难找到测试其他类的方法。

最佳答案

简答:

您应该模拟/ stub 任何不受您的 SUT 直接控制的东西。只测试 SUT 的行为,永远不要编写试图确认超出该范围的行为的测试(即测试模拟/ stub )。


长答案:

只见树木不见森林。当您是编写所有代码的人时,您有时会发现很难避免对实现细节进行过于细粒度的测试。

您想要测试行为的想法是正确的,所以当您开始考虑测试时,危险信号就消失了。这正是 TDD 的全部意义所在,因为它有助于暴露设计缺陷。但请记住,只测试 SUT 的行为。其他一切都应该在你的单元测试(模拟)的控制之下,否则它就不是单元测试。

将您自己置于 LinkDisplayer 类的使用者的位置,并问自己“我将如何在生产代码中使用它?”您可能只是调用该方法并期望它起作用。您肯定不会调用数据库来确保它确实检索了正确数量的元素,或者它们是按类别排序的,对吗?那么为什么要尝试为此编写测试。

调用 displayLatestLinksByCategory 的最终结果应该是什么?

根据您的示例,我看到了该问题的两个可能答案,以及您应该根据这些答案采取什么行动:

  1. 使用特定方法从数据库中获取一些内容,并将其显示在某处。
    • 如果这就是该方法的作用,那么您应该测试的只有这两件事。主要是,使用正确的参数在数据访问组件上调用了正确的方法;并且返回的数据到达了它需要去的地方。
    • 您应该测试的是返回数据的形状***,因为这只会测试您的测试已经完全控制的行为。这就像测试您刚刚在测试中设置为 true 的变量实际上是否为 true。
    • 使用特定方法从数据库中获取一些东西并将其返回
    • 在这一点上,红旗应该到处都是。如果这是此方法唯一有用的地方,那么您必须问问自己为什么不直接调用数据访问方法?作为此类的使用者,您已经可以控制正在使用的数据访问组件(您提供了它),所以为什么要有中间人。

* 可以测试您的 SUT 如何响应特定形状的数据。如果返回 null 或集合为空,您可能希望抛出异常。如果返回的值多于 N,您可能希望从列表中剪掉额外的值,但您永远不想测试超出 SUT 行为的内容。因为您可以直接控制从模拟返回的数据的形状,所以测试可能会导致最糟糕的测试;一个不测试任何东西但仍然通过的测试。

关于使用 DAO 测试对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1268068/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com