无法模拟静态方法 Powermock 中的函数



我正在使用 junit 和 mockito 为下面的代码编写单元测试

public class Abc implements Runnable
{
private static ServerSocket server;  
private static int port;      
public Abc(int cPort)
{
port = cPort;
}
public void run()
{
init();
}
public static void init()
{
try {
server = new ServerSocket(port);
...something...
client.close();
} 
}
catch(IOException e)
{   
System.out.println("Exception inside init()...");
e.printStackTrace();
}
}
};

我写的单元测试

@RunWith(PowerMockRunner.class)
@PrepareForTest({ServerSocket.class})
public class abcTest {
@Mock (name = "server") //same name as private var.
ServerSocket mockServer;        
@InjectMocks
Abc abc;
@Test
public void testInit() throws Exception {
int port = 1880;
Socket mockClient = Mockito.mock(Socket.class);  
PowerMockito.whenNew(ServerSocket.class).
withArguments(anyInt()).thenReturn(mockServer);         
abc = new Abc(port);
Abc.init();         
PowerMockito.verifyNew(ServerSocket.class).withArguments(port);
}
};

但是调用始终转到原始函数定义。我正在使用带有 mockito 2.28.2 和 powermockito 2.0.2 的 junit 4.11。很长一段时间后,我正在使用java。现在它感觉有点新。如果代码中有任何错误,请纠正我。

您需要更改PrepareForTest注释 到@PrepareForTest({Abc.class}).

来自PowerMockitodocu

此注释告诉 PowerMock 准备某些类进行测试。需要使用此注释定义的类通常是那些需要字节码操作的类

在本例中,这是指创建ServerSocket的新实例的类。
ServerSocket本身是一个non-finalpublic类,不需要PowerMockito的特殊处理(相反Mockito可以自己处理这个类(。


您还可以更改测试以执行以下操作:

@Test
public void testInit() throws Exception {
int port = 1880;
ServerSocket mockServer = Mockito.mock(ServerSocket.class);
PowerMockito.whenNew(ServerSocket.class)
.withArguments(Mockito.anyInt()).thenReturn(mockServer);
Abc.port = port;
Abc.init();     
PowerMockito.verifyNew(ServerSocket.class).withArguments(port);
}

  • (第一点与测试是失败还是成功无关(
    我不知道为什么您将对象和静态方法的行为混合在一起,但我认为您应该改变这一点。

    在测试中,而不是创建一个ABC对象,只是可以直接设置静态端口变量。
    或者将整个ABC类更改为一个对象。

  • @InjectMocks失败了,因为没有默认构造函数
    (实际上我在尝试执行代码时在控制台中收到错误消息(

  • 此外,您在测试中创建 ABC 的新实例,该实例将覆盖注释所做的操作。此外,由于server是在init调用期间创建的,因此无需为其注入模拟。

  • powermockito 2.0.2实际上取决于junit 4.12,所以我不确定降级到旧版本会产生什么影响。

  • Socket mockClient似乎与您发布的代码有些无关,所以我在答案中将其从我的示例中删除,但是当您在代码中使用client(我假设这是您的Socket(时,您可能也需要为此做一些模拟,并相应地为该方法提供模拟。

相关内容

  • 没有找到相关文章

最新更新