Junit Mock 重复假装客户端调用,但只有最后一个 Mock 多次返回

Junit Mock Repeated Feign Client Calls but Only the Last Mock Returned Multiple Times

我有一个 Spring 启动应用程序,它使用 Feign Client 调用微服务以在创建新部门时将用户添加到用户 table(新部门将被插入部门 table).请求看起来像:

要求:

 {
  "department": "math",
  "usernameList": ["aaa", "bbb", "ccc"]
 }

用户模型:

 public class User {
    private String username;
 }

Feign 客户端:

 import org.springframework.cloud.openfeign.FeignClient;
 @FeignClient(name = "user-client", url = "/.../user", configuration = UserConfiguration.class)

 public interface UserClient {

     @RequestMapping(method = RequestMethod.POST, value = "users")
     User createUser(User user);
 }

用户服务:

@Service
public class UserService {

private final UserClient userClient;       

public UserResponse createUser(@Valid Request request);

     List<User> userList = request.getUsernameList()
           .stream()
           .map(username -> userClient.createUser(mapToUser(username)) 
           .collect(Collectors.toList());
 ......
}

以上代码有效,我能够将 3 个用户添加到数据库中。 userList 有 3 个正确的用户名。但是,当我 运行 下面的 junit 测试时,似乎只有最后一个 userResp ("ccc") 作为模拟响应返回了 3 次。当我在调试模式下 运行 junit 测试时,我看到每次 thenReturn(userResp) 都有正确的 userResp,但在 UserService 中,userList 最终包含 3 "ccc",而不是一个列表"aaa, bbb, ccc"。我尝试在 UserService 中使用 FOR 循环而不是流,结果是一样的,所以不是因为流。我还尝试删除 Junit 中的 FOR 循环,只调用模拟 3 次,结果相同。我不确定这是否与 Feign 客户端模拟有关,或者我是否在测试用例中做错了什么。有人可以帮忙吗?

我的 Junit:

 public class UserTest {

    @MockBean
    private UserClient userClient;  

    @Test
    public void testAddUser() throws Exception {

        for (int i=1; i<=3; i++) {

             User userResp = new User();

              if (i==1) {
             userResp.setUsername("aaa");
            // mock response
       Mockito.when(userClient.createUser(ArgumentMatchers.any(User.class)))
         .thenReturn(userResp);
           }
           if (i==2) {
             userResp.setUsername("bbb");
            // mock response
       Mockito.when(userClient.createUser(ArgumentMatchers.any(User.class)))
         .thenReturn(userResp);
           }
        if (i==3) {
             userResp.setUsername("ccc");
            // mock response
       Mockito.when(userClient.createUser(ArgumentMatchers.any(User.class)))
         .thenReturn(userResp);
           }
       }

       // invoke the real url
       MvcResult result = mockMvc.perform(post("/users")
            .content(TestUtils.toJson(userRequest, false))
            .contentType(contentType))
            .andDo(print())
            .andExpect(status().isCreated())
            .andReturn();  
    }

要使方法 return 为后续调用设置不同的值,您可以使用

Mockito.when(userClient.createUser(ArgumentMatchers.any(User.class)))
            .thenReturn("aaa")
            .thenReturn("bbb")
            .thenReturn("ccc"); //any

// Or a bit shorter with varargs:

    Mockito.when(userClient.createUser(ArgumentMatchers.any(User.class)))
        .thenReturn("aaa", "bbb", "ccc"); //any