【发布时间】:2019-10-19 19:36:31
【问题描述】:
我有一个 Spring Boot 应用程序,它使用 Feign Client 调用微服务以在创建新部门时将用户添加到 User 表中(新部门将插入到 Department 表中)。请求如下所示:
请求:
{
"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, cc”。我尝试在 UserService 中使用 FOR 循环而不是流,结果是一样的,所以不是因为流。我还尝试删除 Junit 中的 FOR 循环,只调用了 3 次模拟,结果相同。我不确定这是否与 Feign 客户端嘲笑有关,或者我在测试用例中做错了什么。有人可以帮忙吗?
我的朱尼特:
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();
}
【问题讨论】:
-
它在每种情况下都返回“ccc”,因为您每次都在模拟同一个调用 Mockito.when(userClient.createUser(ArgumentMatchers.any(User.class))) .thenReturn(userResp);并且由于“ccc”是最后一个模拟它返回的“ccc”
-
当i==1时,userResp有“aaa”,不应该是第一次返回“aaa”吗?或者 Junit 将 3 个调用视为 1 个调用,因为它是同一个模拟调用?
-
不,因为当您进行实际服务调用时,userResp 的值设置为“ccc”
-
我明白了。因此,并不是每次服务调用 createUser 时都会调用模拟。在调用服务调用之前执行所有模拟......
-
没错,我提出了一种可以帮助您处理案件的方法
标签: spring-boot junit spring-cloud-feign