Java 使用ServerSocket类对方法进行单元测试的最佳方法是什么?
我有这样一种方法:Java 使用ServerSocket类对方法进行单元测试的最佳方法是什么?,java,unit-testing,junit,mocking,serversocket,Java,Unit Testing,Junit,Mocking,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;
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类 对于您当前的代码,新的调用使得测试变得困难 将serversocket的实例注入到方法/类中 然后可以注入一个模拟实例进行测试
我总是发现一个很好的模拟框架使用PowerMock可以模拟构造函数。 因此,对要模拟的类的匹配构造函数的所有调用都可以返回一个模拟实例,您将在测试中准备该实例 您的测试将需要以下注释:
@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
ServerSocket
实例应该可以通过factory获得,该(factory)适用于您的类:
// Passing factory dependency via constructor injection
public PortChecker(IServerSocketFactory socketFactory)
{
this.socketFactory = socketFactory;
}
// ...
ServerSocket ss = this.socketFactory.GetServerSocket(port.getPortNumber());
ss.getLocalPort();
ss.close();
然后,在单元测试中,您可以socketFactory
返回假服务器套接字,从而将其与任何真实系统“断开”
请注意,ServerSocket
可能还需要是抽象的(比如,由接口/基类表示),这样它也可以被模拟
public boolean isFree(LdapPort port) {
try{
new ServerSocket(port.getPortNumber()).close();
return true;
} catch(IOException ex){
return false;
}
}
您可以通过在同一端口上创建ServerSocket来测试它,isFree应该为false,然后关闭ServerSocket,isFree应该为true