单元测试使用ServerSocket类的方法的最佳方法是什么?
问题描述:
我有一个这样的方法:单元测试使用ServerSocket类的方法的最佳方法是什么?
public boolean isFree(LdapPort port) {
boolean result = false;
try{
ServerSocket ss = new ServerSocket(port.getPortNumber());
ss.getLocalPort();
ss.close();
} catch(IOException ex){
result = true;
}
return result;
}
的问题是,getLocalPort()
真实系统端口操作和测试期间,它通过不同的本地系统上。
应该用什么来测试这种方法的有效方法是什么?
答
的ServerSocket
实例应该通过工厂,(工厂)是passed as a dependency到类可供选择:
// Passing factory dependency via constructor injection
public PortChecker(IServerSocketFactory socketFactory)
{
this.socketFactory = socketFactory;
}
// ...
ServerSocket ss = this.socketFactory.GetServerSocket(port.getPortNumber());
ss.getLocalPort();
ss.close();
然后,在你的单位te ST可以mocksocketFactory
返回假服务器插槽,因此从任何真实世界系统“脱节”了。
注意ServerSocket
也可能需要抽象(比如,通过接口/基类来表示),所以它也可以被嘲笑。
答
你需要看看嘲讽了ServerSocket类。
根据您目前的代码调用新的测试,使硬盘。
注入的ServerSocket的实例为您的方法/类 然后你可以注入模拟实例进行测试
我一直觉得mockito一个很好的模拟框架
答
使用PowerMock你可以嘲笑构造,details。 因此,所有的来电要嘲笑可以返回一个模拟实例,你会在你准备考试类的匹配的构造。
您的测试将要求这些注释:
@RunWith(PowerMockRunner.class)
@PrepareForTest(ServerSocket.class)
然后测试方法中:
ServerSocket ssMock = createMock(ServerSocket.class);
expectNew(ServerSocket.class, port.getPortNumber()).andReturn(ssMock); // so constructor of the ServerSocket class taking this specific port number will return the ssMock instance
expect(ssMock.getLocalPort()).andReturn(10); // when method getLocalPort is invoked return 10
reply(ssMock, ServerSocket.class); // do not forget to specify not only the mock instance (ssMock) but the ServerSocket class as well
答
你可以写
public boolean isFree(LdapPort port) {
try{
new ServerSocket(port.getPortNumber()).close();
return true;
} catch(IOException ex){
return false;
}
}
而且你可以通过创建相同的端口和isFree上一个ServerSocket应该是假的测试,然后关闭的ServerSocket和isFree应该是真实的。