我正在使用Mockito编写一个简单的单元测试。我有一个smiple abstract 类,它实现了Runnable
:
public abstract class MyRunnable implements Runnable {
@Override
public void run() {
doTask();
}
public abstract void doTask();
}
然后,正在测试的函数使用MyRunnable
:
public class MyService {
public void something() {
executor.execute(new MyRunnable() {
@Override
doTask() {
…
}
});
}
}
我的测试用例,我想测试doTask()
已运行:
@Test
public void testSomething() {
…
ArgumentCaptor<MyRunnable> myCaptor = ArgumentCaptor.forClass(MyRunnable.class);
verify(mockMyService).something(myCaptor.capture());
// get what has been captured
MyRunnable myRunnable = myCaptor.getValue();
//verify doTask() has run , but got ERROR.
verify(myRunnable).doTask();
}
我的测试用例会抛出以下错误:
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to verify() is of type and is not a mock!
错误抱怨verify()
只接受模拟对象。那么,如何验证/测试捕获的 MyRunnable
对象是否与Mockito一起运行doTask()
?
答案 0 :(得分:1)
如果您可以控制代码库,则可以通过将使用new
关键字的任何代码移动到单独的Factory类中来使Mockito使代码可以测试...
public class MyService {
private MyRunnableFactory = factory;
public MyService(MyRunnableFactory factory) {
this.factory = factory;
}
public void something() {
executor.execute(factory.createInstance());
}
}
然后你的测试可以简单地注入工厂的模拟,你可以verify
它的行为/交互
@Mock MyRunnableFactory factory;
@Mock MyRunnable myRunnable;
@Test
public void testSomething() {
when(factory.createInstance()).thenReturn(myRunnable);
// method under test
MyService service = new MyService();
service.something();
verify(myRunnable).doTask();
}
我使用经验法则,创建对象的类不应该有任何业务逻辑,因此您不会遇到这些测试问题。这基本上是Single Responsibilty Principal
答案 1 :(得分:0)
您无法通过Mockito执行此操作,因为MyRunnable
是由待测代码创建的。但你可以查看PowerMock因为它允许你模拟构造函数:https://github.com/jayway/powermock/wiki/MockConstructor