【发布时间】:2018-06-02 22:20:21
【问题描述】:
我正在开发一个新项目。这是迄今为止所做的:
- 技术设计。
- 模型类(数据类)。
- 项目中的所有接口(但还没有实现)。
接下来我想做的是实现从骨架(高级方法)到嵌套对象的方法。不过,我想在编写实现之前为每个方法创建一个单元测试。首先实现高级方法不会有任何问题,因为我将使用接口并仅使用 DI 在外部 Java 配置文件中绑定具体实现。
我要实现的第一个方法称为lookForChanges(),它既接受又返回void。这个方法由 Spring 的调度程序 (@Scheduled) 调用,它管理整个过程:它从 DB 检索数据,从 Web 服务检索数据,比较它们,如果有任何变化,它会更新数据库并发送一个发送给客户端的 JMS 消息。当然,它不会自己做所有这些事情,而是调用相关的类和方法。
所以我遇到的第一个问题是如何为 void 方法创建单元测试。在所有教程中,测试的方法总是接受参数并返回结果。我找到了in this question 的答案。他说,即使没有结果要检查,至少可以确保被测方法中的方法被调用并且参数顺序正确。
我有点喜欢这个答案,但问题是我正在使用 TDD,所以与提出这个问题的人不同,我在实现测试方法之前编写测试,所以我还不知道它将使用哪些方法和顺序。我可以猜到,但只有在方法已经实现后,我才能确定这一点。
那么,如何在实现之前测试一个 void 骨架方法?
【问题讨论】:
-
该方法应该做什么?这决定了你应该测试什么。 void 方法更难测试,因为您需要在测试代码中观察副作用,这在某种程度上被认为是一种反模式。那么,
lookForChanges()在被测类的状态下应该修改什么? -
@MickMnemonic 我已经解释了它应该做什么:与 DB 层交互以检索数据,与 Web 服务层交互以检索数据,比较两个地方的数据,如果两者之间存在差异然后它与 DB 层交互以更新 DB,并与 JMS 层交互以向客户端发送通知。它不会更改对象状态(名为 MainService)中的任何内容。
-
很公平。该方法基本上等同于
main(),并且为它编写单元测试当然是可能的,但不会增加太多价值,因为您主要测试与模拟(DB,WS,JMS)的交互。也许可以将数据比较提取到一个单独的、可单元测试的方法/类中? -
@MickMnemonic 是的,当然,此方法不会自己进行比较,而是会调用另一个方法来进行比较。但是我怎样才能测试那个“主要”方法呢?我的意思是如果它没有返回任何值并且我还没有编写实现,我可以测试什么?如果我确实编写了实现,我至少可以测试所有方法都被调用(使用间谍),以防有人删除任何行。
-
我假设您的意思是您还没有编写依赖项的实现。这就是您使用模拟的目的;如果您的代码使用 DI 并且您针对接口进行编码,那么这应该没问题。我可以尝试在答案中对此进行更多解释。
标签: java unit-testing oop design-patterns tdd