jUnit中的void方法和线程的单元测试

时间:2012-04-11 10:30:20

标签: java unit-testing testing junit

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

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

3 个答案:

答案 0 :(得分:2)

首先,如果您在单元测试中使用真正的SocketChannel,那么它不是单元测试。您应该为Mockito使用模拟(考虑SocketChannel)。这样做将允许您为受测试的方法提供受控的字节流,并验证传递给通道的字节数。

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

您可以直接在单元测试中致电run()

Mockito link

答案 1 :(得分:2)

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

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

理想情况下,您应该同时执行这两项操作,但在现实世界中,单元测试可能并不总是可行。特别是对于这样的低级方法,它依赖于一些外部软件/硬件组件,如套接字,DB,文件系统等。然后,最好的方法是在这些方法/层中保留尽可能少的逻辑(因此几乎没有失败的可能性)。可能,并将逻辑抽象为更高层,设计为可单元测试(使用如上所述的可模拟接口)。

要测试线程,您可以照常从单元测试中run()进行测试。然后,在尝试获取并验证线程产生的结果之前,您很可能需要等待一段时间。

同样,如果你将任务的实际逻辑抽象为例如一个CallableRunnable,你可以更容易地单独测试它。这也使您能够使用Executor framework(现在或以后),这使得处理并发更加容易和安全。

答案 2 :(得分:0)

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

相关问题