为什么Mockbean mockito不能在新线程中工作

cu6pst1q  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(313)

我发现Mockbean可以在测试主线程中工作,但不能在新线程调用中工作,下面是我的演示代码。在新线程中第一次调用mock是工作的,但是当第二次调用demoService时,它返回null(mock不工作)

参考Jar版本mockito-core 4.11.0 JDK1.8 Junit 4 SpringBoot:1.5.22.RELEASE

  1. /***
  2. * demo test case for find why mockito mock not work in new thread
  3. */
  4. @RunWith(SpringJUnit4ClassRunner.class)
  5. @SpringBootTest(classes = DemoApplication.class)
  6. public class DemoApplicationTests {
  7. @MockBean
  8. protected DemoService demoService;
  9. /**
  10. * call the mock in main thread, the mock all work
  11. */
  12. @Test
  13. public void testNormalCase_work() {
  14. DemoServiceMock.mockdoSomething(demoService);
  15. String result = demoService.doSomething("324234");
  16. System.out.println("return: " + result);
  17. String result2 = demoService.doSomething("324234");
  18. System.out.println("return2: " + result);
  19. }
  20. /***
  21. * call the mock in new thread
  22. * When call the demoService in second times, it return null (mock not work)
  23. */
  24. @Test
  25. public void testInNewThread_notWork() {
  26. DemoServiceMock.mockdoSomething(demoService);
  27. Thread t = new Thread(new Runnable() {
  28. public void run() {
  29. //for the first time call, the mock is work
  30. String result = demoService.doSomething("324234");
  31. System.out.println("return in thread: " + result);
  32. //for this second time call in new thread, the mock not work and return null
  33. String result2 = demoService.doSomething("324234");
  34. System.out.println("return2 in thread: " + result2);
  35. }
  36. });
  37. t.start();
  38. }
  39. }
  40. public class DemoServiceMock {
  41. public static void mockdoSomething(DemoService demoService){
  42. Mockito.doReturn("mockReturnValue").when(demoService).doSomething(any());
  43. }
  44. }

我发现Mockbean可以在测试主线程中工作,但不能在新线程调用中工作,下面是我的演示代码。在新线程中第一次调用mock是工作的,但是当第二次调用demoService时,它返回null(mock不工作)

参考Jar版本mockito-core 4.11.0 JDK1.8 Junit 4 SpringBoot:1.5.22.RELEASE

b4qexyjb

b4qexyjb1#

我无法在本地重现您的行为(但使用JUnit 5、Sping Boot 2和JDK 11)。然而,这是非常可疑的,你不等待你的线程完成。多次运行测试可能会成功或失败,具体取决于语句的执行顺序。
当第二次调用被发出时,测试运行器可能已经关闭并注销了所有stubbing调用。race condition的一个典型例子
等待线程完成可能会“解决”你的问题:

  1. @Test
  2. public void testInNewThread_notWork() {
  3. DemoServiceMock.mockdoSomething(demoService);
  4. Thread t = new Thread(new Runnable() {
  5. public void run() {
  6. //for the first time call, the mock is work
  7. String result = demoService.doSomething("324234");
  8. System.out.println("return in thread: " + result);
  9. //for this second time call in new thread, the mock not work and return null
  10. String result2 = demoService.doSomething("324234");
  11. System.out.println("return2 in thread: " + result2);
  12. }
  13. });
  14. t.start();
  15. t.join(); // wait for thread to complete execution!
  16. }

PS帮你自己一个忙,停止使用过时的/生命周期结束的软件和库。有JUnit 5、Sping Boot 3和JDK 17。所有后者仍然获得更新和安全修复,而您的版本仍然未维护且易受攻击。

展开查看全部

相关问题