Java 如何使用mockitoinline模拟子线程的run()方法

Java 如何使用mockitoinline模拟子线程的run()方法,java,multithreading,junit,java-8,mockito,Java,Multithreading,Junit,Java 8,Mockito,代码说明: MainThread根据用户列表创建ChildThread-每个用户一个ChildThread。我正在尝试为MainThread编写一个单元测试用例,我想跳过ChildThread的实现(将为ChildThread编写一个单独的单元测试用例)。下面是代码片段 @Slf4j public class MainThread implements Runnable { private static final UserService USER_SERVICE = ApplicationC

代码说明: MainThread根据用户列表创建ChildThread-每个用户一个ChildThread。我正在尝试为MainThread编写一个单元测试用例,我想跳过ChildThread的实现(将为ChildThread编写一个单独的单元测试用例)。下面是代码片段

@Slf4j
public class MainThread implements Runnable {
 private static final UserService USER_SERVICE = ApplicationContextUtils.getApplicationContext().getBean("userService", UserService.class);
 private final String threadName;

 public MainThread(String threadName) {
    this.threadName = threadName;
 }

 public void run() {
    log.info("{} thread created at {}", threadName, LocalDateTime.now());
    List<UsersDTO> usersDTOs = USER_SERVICE.getUsers();
    ExecutorService executor = Executors.newFixedThreadPool(usersDTOs.size());
    usersDTOs.stream().map(ChildThread::new).forEach(executor::execute);
    executor.shutdown();
 }
}

@Slf4j
 public class ChildThread implements Runnable {
 private final UserDTO userDTO;

 public ChildThread(UserDTO userDTO) {
    this.userDTO = userDTO;
 }

 public void run() {
    log.info("Child thread created for user: {}", userDTO.getName());
    // some business logic
 }
}

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MainThreadTest {

 @Mock
 private ApplicationContext applicationContext;
 @Mock
 private UserService userService;

 @BeforeEach
 public void setUp() {
    MockitoAnnotations.openMocks(this);
    new ApplicationContextUtils().setApplicationContext(applicationContext);
 }

 @Test
 void test() {
    Mockito.when(applicationContext.getBean("userService", UserService.class)).thenReturn(userService);
    Mockito.when(userService.getUsers()).thenReturn(MockObjectHelper.getUsersList());

    ChildThread childThread = new ChildThread(MockObjectHelper.getUser());
    ChildThread spy = spy(childThread);
    doNothing().when(spy).run();

    MainThread mainThread = new MainThread("TestingThread");
    mainThread.run();

    verify(userService, times(1)).getUsers(any());
 }
}
@Slf4j
公共类主线程实现可运行{
私有静态最终用户服务USER\u SERVICE=ApplicationContextils.getApplicationContext().getBean(“用户服务”,UserService.class);
私有最终字符串threadName;
公共主线程(字符串threadName){
this.threadName=threadName;
}
公开募捐{
info(“{}线程创建于{}”,threadName,LocalDateTime.now());
List usersDTOs=USER_SERVICE.getUsers();
ExecutorService executor=Executors.newFixedThreadPool(usersDTOs.size());
usersDTOs.stream().map(ChildThread::new).forEach(executor::execute);
executor.shutdown();
}
}
@Slf4j
公共类ChildThread实现可运行{
私有最终用户到用户;
公共子线程(UserDTO UserDTO){
this.userDTO=userDTO;
}
公开募捐{
info(“为用户创建的子线程:{}”,userDTO.getName());
//一些商业逻辑
}
}
@TestInstance(TestInstance.Lifecycle.PER_类)
公共类线程测试{
@嘲弄
私有应用程序上下文应用程序上下文;
@嘲弄
私人用户服务;
@之前
公共作废设置(){
MockitoAnnotations.openMocks(这个);
新建ApplicationContextIls().setApplicationContext(applicationContext);
}
@试验
无效测试(){
Mockito.when(applicationContext.getBean(“userService”,userService.class)).thenReturn(userService);
Mockito.when(userService.getUsers()).thenReturn(MockObjectHelper.getUsersList());
ChildThread ChildThread=新的ChildThread(MockObjectHelper.getUser());
ChildThread spy=spy(ChildThread);
doNothing().when(spy.run();
MainThread MainThread=新的主线程(“testingread”);
mainThread.run();
验证(userService,times(1)).getUsers(any());
}
}
尽管监视ChildThread,但仍会执行ChildThread的run()方法。doNothing().when(spy.run();没有效果。由于某些原因,我不能使用PowerMockito。如何使用mockito内联(3.10.0版)和java8实现这一点


任何帮助都将不胜感激。

不要模仿ChildThread重构主线程,以便在构造函数中注入ExecutorService


然后模拟ExecutorService并检查它是否接收到正确的ChildThread实例。

问题出在这里
usersDTOs.stream().map(ChildThread::new).forEach(executor::execute)
因为它创建的是真实对象,而不是模拟。您应该将
ChildThread
creation替换为其他服务,或者以某种方法创建,您可以使用这种方法。谢谢@Alex