【问题标题】:Mockito failure: Actually, there were zero interactions with this mockMockito 失败:实际上,与这个 mock 的交互为零
【发布时间】:2017-07-17 15:50:12
【问题描述】:

我正在尝试使用 JUnit、Mockito、Spring 测试和 Spring Security 测试来测试 spring rest 控制器类。以下是我正在执行测试的休息控制器类;

@RestController
public class EmployeeRestController {

    @Autowired
    private EmployeeService employeeService;

    @PreAuthorize("hasAnyRole('ROLE_EMPSUPEADM')")
    @RequestMapping(value = "/fetch-timezones", method = RequestMethod.GET)
    public ResponseEntity<List<ResponseModel>> fetchTimeZones() {
        List<ResponseModel> timezones = employeeService.fetchTimeZones();
        return new ResponseEntity<>(timezones, HttpStatus.OK);
    }

}

以下是我的测试类;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
@WebAppConfiguration
public class EmployeeRestControllerUnitTest {

private MockMvc mockMvc;

@Autowired
private WebApplicationContext webApplicationContext;

@Mock
private EmployeeService employeeService;

@InjectMocks
private EmployeeRestController employeeRestController;

@Before
public void init() {
    MockitoAnnotations.initMocks(this);
    Mockito.reset(employeeService);
    mockMvc = MockMvcBuilders
                .webAppContextSetup(webApplicationContext)
                .build();
}

@Test
@WithMockUser(roles = {"EMPSUPEADM"})
public void testFetchTimezones() {
    try {
        mockMvc.perform(get("/fetch-timezones"))
          .andExpect(status().isOk())               
          .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
          .andExpect(jsonPath("$", hasSize(4)));
        verify(emploeeService, times(1)).fetchTimeZones();
        verifyNoMoreInteractions(employeeService);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

我参考了很多教程制作了上面的测试类。问题是我无法清楚地理解一切。所以,我有以下疑问。

  1. 我正在创建一个 EmployeeService 的模拟并使用 @InjectMocks 将其注入 EmployeeRestController,那么为什么会出现以下故障;

    Wanted but not invoked:
    careGroupService.fetchTimeZones();
    -> at com.example.api.test 
    .restcontroller.EmployeeRestControllerUnitTest 
    .testFetchTimezones(EmployeeRestControllerUnitTest.java:73)
    Actually, there were zero interactions with this mock.
    
  2. MockMvcBuilders.webAppContextSetup(webApplicationContext).build();工作正常。

  3. 我知道 MockMvcBuilders.standaloneSetup(employeeRestController) 用于测试单个控制器类,并且此方法无法使用 spring 配置。我们如何为这种方法提供弹簧配置,是否可能。

  4. 最后,这段代码是怎么做的:Mockito.reset(employeeService);有效。

【问题讨论】:

    标签: spring-mvc junit mockito spring-test spring-restcontroller


    【解决方案1】:

    1) 你确实验证了

    verify(emploeeService, times(1)).fetchTimeZones();
    

    但您没有为它设置模拟行为(在您调用 mockMvc.perform(get("/fetch-timezones")) 之前)。

    List<ResponseModel> timezones = new ArrayList<>();
    when(emploeeService.fetchTimeZones()).thenReturn(timezones );
    

    2) 从上下文创建 MockMvc。 mockmvc 模拟 Web 容器,尽可能使用 mock,但支持 http 调用并提供调用控制器的可能性。

    它支持 Dispatcher Servlet 和所有必需的 MVC 组件, 允许我们在适当的 Web 环境中测试端点,但是 无需运行服务器的开销。

    3) 使用时:

    @MockBean private EmployeeService employeeService;
    

    你覆盖了真正的服务。将其从测试类中删除,实际服务将用于测试。而不是使用@Mock 使用@MockBean。 @MockBean 它被容器覆盖,@Mock 你需要通过反射将它注入控制器

    或者没有带反射的弹簧靴:

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
        Mockito.reset(employeeService);
        mockMvc = MockMvcBuilders
                    .webAppContextSetup(webApplicationContext)
                    .build();
        EmployeeRestController employeeRestController=  
                webAppContext.getBean(EmployeeRestController.class);
        ReflectionTestUtils.setField(employeeRestController, 
                                     "employeeService",
                                     employeeService);
    }
    

    4) Mockito.reset(employeeService);- 你重置了之前设置的所有行为。 Mock 包含来自when(), verify() 的信息并对其进行控制,调用 reset - 它会清除所有信息。

    【讨论】:

    • 您好,感谢您的回答。但我仍然收到同样的失败消息。
    • 对不起,我没有使用弹簧靴。
    • 感谢您的帮助,我能够按照Link 中的建议通过提供 测试上下文 来实现它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多