3

我是单元测试的新手。我了解它的原理,但我仍然不知道如何测试我当前的项目。我需要测试 void 方法,使用 java.nio.SocketChannel 操作。这些方法是:
- initSelector,我打开选择器,绑定新的 ServerSocketChannel 并注册它
- 读取,它读取数据并将其放入队列(我是否应该编写额外的方法来验证,如果该数据确实存在于队列中?情况下,我应该为这些方法编写测试吗?)
- write 方法,它从队列中获取数据并将其写入 SocketChannel

我可以测试这些方法是否不抛出 IOException,但是还有什么?
我应该如何测试线程的 run() 方法?还是不是单元测试,而是系统或其他?

4

3 回答 3

2

因此,首先,如果您在单元测试中使用实数SocketChannel,则它不是单元测试。您应该MockitoSocketChannel. 这样做将允许您向被测方法提供受控的字节流,并验证将哪些字节传递给通道。

如果您的类正在创建 的实例SocketChannel,请考虑将类更改为接受SocketChannelFactory. 然后你可以注入一个SocketChannelFactory返回模拟的SocketChannel模拟。

您可以run()直接在单元测试中调用。

模拟链接

于 2012-04-11T10:35:29.447 回答
2

基本上,您有两种可能性:

  • 如果你想对这些方法进行彻底的单元测试,你应该将具体的(硬件依赖组件,如套接字等)隐藏在可模拟接口后面,并在单元测试中使用模拟来验证对这些对象进行了具有预期参数的预期调用
  • 或者您可以使用整个组件/应用程序中的真实套接字编写集成/系统测试,以验证是否打开了正确的套接字、正确传输数据等。

理想情况下,您应该两者都做,但在现实世界中,单元测试可能并不总是可行的。特别是对于这样的低级方法,它们依赖于一些外部软件/硬件组件,如套接字、数据库、文件系统等。那么最好的方法是在这些方法/层中留下尽可能少的逻辑(因此尽可能少的失败可能性)可能,并将逻辑抽象到更高层,设计为可单元测试(使用如上所述的可模拟接口)。

要测试线程,您可以run()像往常一样从单元测试中获取它们。然后很可能您需要等待一段时间才能尝试获取并验证线程产生的结果。

同样,如果您将任务的实际逻辑抽象为例如 a Callableor Runnable,则可以更轻松地对其进行单独的单元测试。这也使您能够使用Executor 框架(现在或以后),这使得处理并发更加容易和安全。

于 2012-04-11T10:39:15.720 回答
0

run() 是一个和其他方法一样的方法,所以你应该能够从单元测试中调用它(当然取决于它是否在无限循环中运行 - 那么你可能想要测试 run() 正在调用的方法)。
对于 SocketChannel,我想说你不想测试 SocketChannel 本身;你想测试你的代码如何与给定一组启动条件的 SocketChannel 交互。
所以你可以考虑为它创建一个模拟,并让你的代码与模拟对话。这样您就可以验证您的代码是否以您期望的方式(read()、write() 等)与通道交互。
例如,查看http://code.google.com/p/powermock/

于 2012-04-11T10:41:15.203 回答