我正在使用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);
}
};
但是调用总是转到原始函数定义。我正在将junit 4.11与mockito 2.28.2和powermockito 2.0.2一起使用。我使用Java很久了。现在感觉就像是新的一样。如果代码中有任何错误,也请纠正我。
答案 0 :(得分:1)
您将需要更改PrepareForTest
批注
到@PrepareForTest({Abc.class})
。
从PowerMockito docu
:
此注释告诉PowerMock准备某些类进行测试。需要使用此注释定义的类通常是那些需要字节码操作的类
在这种情况下,它引用创建ServerSocket
的新实例的类。
ServerSocket
本身是一个non-final
public
类,不需要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
时(我假设您的{{1 }})在您的代码中,您可能还需要对此进行一些模拟,并相应地向该方法提供模拟。