我是单元测试的新手。我理解它的原理,但我仍然无法弄清楚如何测试我当前的项目。我需要测试void方法,使用java.nio.SocketChannel进行操作。这些方法是:
- initSelector,我打开选择器,绑定新的ServerSocketChannel并注册它
- 读取,读取数据并将其放入队列(我是否应该编写额外的方法来验证,如果该数据实际存在于队列中?在那种情况下,我应该为这些方法编写测试吗?)
- write方法,从队列中获取数据并将其写入SocketChannel
我可以测试这个方法不抛出IOException,但还有什么?
我应该如何测试Thread的run()方法?或者它不是单元测试,而是系统或其他?
答案 0 :(得分:2)
首先,如果您在单元测试中使用真正的SocketChannel
,那么它不是单元测试。您应该为Mockito
使用模拟(考虑SocketChannel
)。这样做将允许您为受测试的方法提供受控的字节流,并验证传递给通道的字节数。
如果您的班级正在创建SocketChannel
的实例,请考虑更改班级以接受SocketChannelFactory
。然后你可以注入一个SocketChannelFactory
模拟器,它返回一个SocketChannel
模拟器。
您可以直接在单元测试中致电run()
。
答案 1 :(得分:2)
基本上,您有两种可能性:
理想情况下,您应该同时执行这两项操作,但在现实世界中,单元测试可能并不总是可行。特别是对于这样的低级方法,它依赖于一些外部软件/硬件组件,如套接字,DB,文件系统等。然后,最好的方法是在这些方法/层中保留尽可能少的逻辑(因此几乎没有失败的可能性)。可能,并将逻辑抽象为更高层,设计为可单元测试(使用如上所述的可模拟接口)。
要测试线程,您可以照常从单元测试中run()
进行测试。然后,在尝试获取并验证线程产生的结果之前,您很可能需要等待一段时间。
同样,如果你将任务的实际逻辑抽象为例如一个Callable
或Runnable
,你可以更容易地单独测试它。这也使您能够使用Executor framework(现在或以后),这使得处理并发更加容易和安全。
答案 2 :(得分:0)
run()是一个像任何其他方法一样的方法,所以你应该只能从单元测试中调用它(取决于它是否在无限循环中运行 - 然后你可能想测试运行的方法( )正在打电话)
对于SocketChannel我会说你不想测试SocketChannel本身;你想测试你的代码如何在给定一组启动条件的情况下与SocketChannel交互。
所以你可以考虑为它创建一个模拟,并让你的代码与模拟对话。这样您就可以验证代码是否以您期望的方式与通道交互(read(),write()等)。
例如,请查看http://code.google.com/p/powermock/。