我发现Mockbean在测试主线程中工作,但在新线程调用中不起作用,以下是我的演示代码。在新线程中第一次调用mock可以工作,但是当第二次调用demoService时,它返回null(mock不起作用)
##参考Jar版本 模拟核心 4.11.0 JDK1.8 朱尼特4 SpringBoot:1.5.22.RELEASE
/***
* demo test case for find why mockito mock not work in new thread
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class DemoApplicationTests {
@MockBean
protected DemoService demoService;
/**
* call the mock in main thread, the mock all work
*/
@Test
public void testNormalCase_work() {
DemoServiceMock.mockdoSomething(demoService);
String result = demoService.doSomething("324234");
System.out.println("return: " + result);
String result2 = demoService.doSomething("324234");
System.out.println("return2: " + result);
}
/***
* call the mock in new thread
* When call the demoService in second times, it return null (mock not work)
*/
@Test
public void testInNewThread_notWork() {
DemoServiceMock.mockdoSomething(demoService);
Thread t = new Thread(new Runnable() {
public void run() {
//for the first time call, the mock is work
String result = demoService.doSomething("324234");
System.out.println("return in thread: " + result);
//for this second time call in new thread, the mock not work and return null
String result2 = demoService.doSomething("324234");
System.out.println("return2 in thread: " + result2);
}
});
t.start();
}
}
public class DemoServiceMock {
public static void mockdoSomething(DemoService demoService){
Mockito.doReturn("mockReturnValue").when(demoService).doSomething(any());
}
}
我发现Mockbean在测试主线程中工作,但在新线程调用中不起作用,以下是我的演示代码。在新线程中第一次调用mock可以工作,但是当第二次调用demoService时,它返回null(mock不起作用)
##参考Jar版本 模拟核心 4.11.0 JDK1.8 朱尼特4 SpringBoot:1.5.22.RELEASE
我无法在本地重现您的行为(尽管使用 JUnit 5、Spring Boot 2 和 JDK 11)。 然而,如果您不等待线程完成,则非常可疑。多次运行测试可能成功也可能失败,具体取决于语句的执行顺序。
当进行第二次调用时,测试运行程序可能已关闭并取消注册任何存根调用。 竞争条件
的一个主要示例等待线程完成可能会“解决”您的问题:
@Test
public void testInNewThread_notWork() {
DemoServiceMock.mockdoSomething(demoService);
Thread t = new Thread(new Runnable() {
public void run() {
//for the first time call, the mock is work
String result = demoService.doSomething("324234");
System.out.println("return in thread: " + result);
//for this second time call in new thread, the mock not work and return null
String result2 = demoService.doSomething("324234");
System.out.println("return2 in thread: " + result2);
}
});
t.start();
t.join(); // wait for thread to complete execution!
}
PS 帮自己一个忙,停止使用过时/报废的软件和库。有 JUnit 5、Spring Boot 3 和 JDK 17。所有后者仍然可以获得更新和安全修复,而您的版本仍然不受维护且容易受到攻击。