如何最佳地使用ServerSocket类对方法进行单元测试?

3

我有这样一个方法:

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() 操作的是真实的系统端口,在测试过程中会根据本地系统而变化。
那么,应该如何有效地测试这种方法呢?
4个回答

3

ServerSocket 实例应该通过工厂模式可用,该工厂模式作为依赖项传递给你的类:

// 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可能还需要抽象化(例如,由接口/基类表示),以便也可以进行模拟。


1
使用PowerMock,您可以模拟构造函数,详情。因此,您想要模拟的类的所有匹配构造函数的调用都可以返回一个mock实例,在测试中进行准备。
您的测试将需要这些注释:
@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

0

你需要研究一下如何模拟 serverSocket 类。

使用当前的代码,新的调用会使测试变得困难。

将 serversocket 的实例注入到你的方法/类中,然后你可以为测试注入一个模拟实例。

我一直觉得 mockito 是一个很好的模拟框架。


-1

你可以写

public boolean isFree(LdapPort port) {
    try{
        new ServerSocket(port.getPortNumber()).close();
        return true;
    } catch(IOException ex){
        return false;
    }
}

你可以通过在相同的端口上创建ServerSocket并使isFree为false来测试它,然后关闭ServerSocket,此时isFree应该为true。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接