以下类在另一个线程上调用函数MyService::execute
。
public class Foo
{
@Inject
private MyService m_service;
@Inject
private ExecutorService m_executor;
public void foo()
{
MyRequest myRequest = new MyRequest("bar");
System.out.println("TP1");
m_executor.execute( () ->
{
System.out.println("TP2");
m_service.execute(myRequest);
System.out.println("TP3");
} );
System.out.println("TP4");
}
}
我创建了一些单元测试,用正确的参数检查execute
。 MyService
被嘲笑。
public class FooTests
{
private final MyService m_myService = Mockito.mock(MyService.class);
@Test
public final void foo1()
{
final ExecutorService executor = Executors.newSingleThreadExecutor();
InjectionBinder injectionBinder = new InjectionBinder(m_myService, executor);
// some code that calls foo()
ArgumentCaptor<MyRequest> argument = ArgumentCaptor.forClass(MyRequest.class);
Mockito.verify(m_myService, Mockito.times(1)).execute(argument.capture());
// check arguments
}
@Test
public final void foo2()
{
final ExecutorService executor = Executors.newSingleThreadExecutor();
InjectionBinder injectionBinder = new InjectionBinder(m_myService, executor);
// some code that calls foo()
ArgumentCaptor<MyRequest> argument = ArgumentCaptor.forClass(MyRequest.class);
Mockito.verify(m_myService, Mockito.times(1)).execute(argument.capture());
// check arguments
}
}
测试在Windows和OSX上运行正常,但foo2
经常在Linux上运行。
失败的原因是没有调用mock:
org.mockito.exceptions.verification.WantedButNotInvoked:
Wanted but not invoked:
myService.execute(<Capturing argument>);
-> at FooTests.foo2(#line number)
Actually, there were zero interactions with this mock.
但是我确实看到m_service.execute
中对Foo
的调用附近的打印报表。
我正在使用JUnit 4.12和Mockito 2.2.26。
我错过了什么?
修改
我已经弄明白了。有时,测试在另一个线程上安排MyService::execute
之前运行完成。
在调用foo
之后,在验证对MyService::execute
的调用之前,在我的测试中添加了一个简短的等待来解决问题。