繁体   English   中英

Spring / Mockito-测试控制器

[英]Spring/Mockito - Testing a controller

这是我写的控制器类,

@RestController
public class TranslatorController {

    @Autowired
    TransResponse transResponse;

    @Autowired
    TransRequest transRequest;

    @Autowired
    TransWorker worker;

    @PostMapping(path = "/trans", consumes = {
            MediaType.APPLICATION_JSON_VALUE }, produces = {
                    MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<TransResponse> translate(@RequestBody TransRequest transRequest,
            Errors error, HttpServletRequest request) {

        logger.info("Starting translation::-->" + transRequest.getTerm());
        String trans = worker.trans(transRequest.getText());
        transResponse.setStatus("OK");
        transResponse.setTrans(trans);
        transResponse.setMessage("SUCCESS");

        return new ResponseEntity<>(transResponse, HttpStatus.OK);
    }

}

这是为此的测试课程,

@WebMvcTest(TranslatorController.class)
@ComponentScan("com.demo.service")
public class TranslatorControllerTest {

    @Mock
    TransRequest transRequest;

    @Mock
    Errors error; 

    @Mock
    HttpServletRequest httpRequest;

    @Mock
    private TranslatorController controllerMock;

    @Autowired
    private MockMvc mockMvc;

    @Mock
    TransWorker worker;

    @Mock
    ResponseEntity<TransResponse> respEntity;

    @Test
    public void testTranslate() throws Exception {
        Mockito.when(worker.trans(Mockito.anyString())).thenReturn("cold");
        TransResponse response = new TransResponse();
        response.setTrans("cold");
        respEntity = new ResponseEntity<TransResponse>(response,
                HttpStatus.OK);
        Mockito.when(controllerMock.translate(transRequest, error, httpRequest)).thenReturn(respEntity);
        respEntity = controllerMock.translate(transRequest, error, httpRequest);
        assertEquals("cold", respEntity.getBody().getTrans());
    }
}

作为成功的过去

但是我的问题是我是否正确进行了测试? 如果不正确。 请您指导我哪里错了。

我认为使用@WebMvcTest很好! 只是您不应该模拟TranslatorController因为@WebMvcTest将为您提供一个实例。

控制器的依赖关系必须是模拟的,这可以通过使用@MockBean进行注释来实现(模拟的实例将注入到控制器中)。

然后,不使用控制器的方法,而使用MockMvc发送测试HTTP请求,该请求将被控制器捕获。

ResultActions result = mockMvc.perform(MockMvcRequestBuilders
                       .post("/trans")
                       .accept(MediaType.APPLICATION_JSON)

                       //whatever JSON content expected as input
                       .content("{trans: \"something\"}")));

resultActions.andExpect(status().isOk());

//validates stuff..
resultActions.andReturn().getResponse().getContentAsString();

整个考试班:

@RunWith(SpringRunner.class)
@WebMvcTest(TranslatorController.class)
public class TranslatorControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    TransResponse transResponse;

    @MockBean
    private TransRequest transRequest;

    @MockBean
    TransWorker worker;

    @Test
    public void testTranslate() throws Exception {
        Mockito.when(worker.trans(Mockito.anyString())).thenReturn("cold");

        ResultActions result = mockMvc.perform(MockMvcRequestBuilders
                               .post("/trans")
                               .accept(MediaType.APPLICATION_JSON)

                               //whatever JSON content expected as input
                               .content("{trans: \"something\"}")));

        resultActions.andExpect(status().isOk()
                     .andExpect(content().string("{trans: \"cold\"}"));

        //validates stuff..
        resultActions.andReturn().getResponse().getContentAsString();
    }
}

这样,您就可以在控制器收到JSON有效负载时实际测试其真实行为。 如果仅调用其方法(也可能是有效的测试),则将无法测试无效的JSON场景或安全性检查(例如,角色用户...)。

该文档显示了示例: https : //spring.io/blog/2016/04/15/testing-improvements-in-spring-boot-1-4

 @RunWith(SpringRunner.class) @WebMvcTest(UserVehicleController.class) public class UserVehicleControllerTests { @Autowired private MockMvc mvc; @MockBean private UserVehicleService userVehicleService; @Test public void getVehicleShouldReturnMakeAndModel() { given(this.userVehicleService.getVehicleDetails("sboot")) .willReturn(new VehicleDetails("Honda", "Civic")); this.mvc.perform(get("/sboot/vehicle") .accept(MediaType.TEXT_PLAIN)) .andExpect(status().isOk()) .andExpect(content().string("Honda Civic")); } } 

我不认为您正在测试想要的东西。 似乎您正在尝试测试控制器的translate方法,但您模拟了控制器。 您不应该嘲笑您要测试的内容。

@RunWith(MockitoJUnitRunner.class)
public class TranslatorControllerTest {

  @InjectMocks
  TranslatorController controller;   

  @Mock
  TransResponse transResponse;

  @Mock
  TransRequest transRequest;

  @Mock
  TransWorker worker;

  @Test
  public void testTranslate() throws Exception {
     Mockito.when(worker.trans(Mockito.anyString())).thenReturn("cold");

     TransResponse response = controller.translate(transRequest, null, new MockHttpServletRequest();
     Assert.assertEquals("cold", response.getBody().getTrans());
  }

}

当然,您还需要测试TransWorker类,因为这实际上是一个调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM