I have a Spring Boot application which uses Feign Client to call a microservice to add users to the User table when a new department is created (new department will be inserted into the Department table). The request looks like:
Request:
{
"department": "math",
"usernameList": ["aaa", "bbb", "ccc"]
}
The User model:
public class User {
private String username;
}
The Feign client:
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);
}
UserService:
@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());
......
}
The above code worked and I was able to add 3 users into the database. The userList has 3 correct username. However, when I ran the junit test below, it seemed that only the last userResp ("ccc") was returned 3 times as mock response. When I ran the junit test in debug mode, I saw that each time the thenReturn(userResp) had the correct userResp, but in the UserService, the userList ended up containing 3 "ccc", rather than a list of "aaa, bbb, ccc". I tried using the FOR loop in the UserService rather than the stream, the result was the same, so it wasn't because of the stream. I also tried to remove the FOR loop in the Junit and just called the mock 3 times, same result. I am not sure if this has something to do with the Feign client mocking or if I did something wrong in my test case. Can someone please help?
My 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();
}