java - 使用 Mock when 方法

标签 java unit-testing mocking mockito

使用 API 为我的 web 应用程序编写一些测试,测试 Controller 方法。 Controller 使用我想模拟的服务方法。 测试代码:

@Mock
private UserService userService;
@Mock
private PasswordEncoder passwordEncoder;
@InjectMocks
private UserApi userApi;

    MockitoAnnotations.initMocks(this);
    mockMvc = MockMvcBuilders.standaloneSetup(userApi).build();

@Test
public void addUser() throws Exception {
    Role role = new Role(1L, "ROLE_USER");
    User user = new User (null, "Test user", "Test password", true,  role);
    when(roleService.findByName(role.getName())).thenReturn(role);
    when(passwordEncoder.encode(user.getPassword())).thenReturn("Encoded password");
    when(userService.save(user)).thenReturn(1L);


    mockMvc.perform(MockMvcRequestBuilders.post("/user").content(user.toJson())).andDo(print())
            .andExpect(status().isOk())
            .andExpect(content().contentType("application/json"))
            .andExpect(content().string(user.toJson()));

}

当 UserService.save(user) 调用时,如果用户的 id 属性为空,它会将其设置为某个唯一的 Long 值。我可以设置 UserService.save(user) 的 Mock 来更改已保存用户的 id,就像真正的 save() 那样吗? 与PasswordEncoder相同,当调用PasswordEncoder.encode(string)时,它会将字符串值更改为编码值,如何说PasswordEncoder的Mock会做同样的事情?

最佳答案

想要这是一个测试气味,可能意味着你测试得太多了;因此,我不会推荐它。您的单元测试正在测试 Spring Controller ,而不是测试 UserServicePasswordEncoder,并且 Spring Controller 没有责任确保用户已更改,或者密码已编码。您可以验证 userServicepasswordEncoder 是否被调用,但这只是测试 Controller 应该做的。

听起来您真正想做的不是模拟 UserService 和 PasswordEncoder ,而是使用真实的类执行端到端测试,例如在测试数据库上。您可以从 Controller 开始发布新用户,然后从测试数据库中取回它并验证您得到的结果是否正确。在这种情况下,您不是对 Spring Controller 进行单元测试,而是对整个真实链进行单元测试。

也就是说,您可以通过使用 thenAnswer 设置自定义答案来完成您所要求的操作。而不是 thenReturn:

when(userService.save(user)).thenAnswer(new Answer<Long>() {
    @Override
    public Long answer(InvocationOnMock invocation) {
        user.setId(1L);
        return 1L;
    }
});

当在模拟上调用该方法时,将调用此自定义答案。其结果将是模拟方法返回的结果。这里,它还在返回之前设置了用户的 id。这仍然相当可怕,最好进行适当的集成测试。

关于java - 使用 Mock when 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39507627/

相关文章:

java - OpenGL 延迟着色照明无法正常工作

java - Guava 中有 Empty 吗?

rest - 通过测试用例,同时给出 500 作为响应

java - 集成测试中 Spring Controller 中的 Mock Feign 客户端

java - 如何返回java中元素的当前索引?

java - 在 Comparable 中使用泛型

java - 如何编写数据访问的单元测试?

Android 单元测试 - 如何在与应用程序相同的项目中运行测试?

mocking - 使用 axios 构造函数时模拟 axios

python - 模拟单元测试引发 "stop called on unstarted patcher"错误