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

4 回答 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可能还需要抽象(例如,由接口/基类表示),因此也可以模拟。

于 2013-05-12T20:24:04.090 回答
1

使用 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
于 2013-05-12T20:23:59.503 回答
0

您需要研究模拟 serverSocket 类。

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

将 serversocket 实例注入您的方法/类,然后您可以注入一个模拟实例进行测试

我一直发现mockito是一个很好的模拟框架

于 2013-05-12T20:21:10.097 回答
-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。

于 2013-05-12T20:38:22.420 回答