首页 > 解决方案 > 如何模拟服务和测试 POST 控制器方法

问题描述

期望控制器方法返回新创建的天气资源,但响应正文为空。

在调用服务方法时模拟服务以返回天气资源。

天气资源的 POST 方法:

    @ApiOperation("Creates a new weather data point.")
    public ResponseEntity<Weather> createWeather(@Valid @RequestBody Weather weather) {     
        try {
            Weather createdWeather = weatherService.createWeather(weather);

            return ResponseEntity.ok(createdWeather);
        } catch(SQLException e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

测试:

    @Test
    public void createWeather_200() throws Exception {
        Weather weather = new Weather(null, "AC", new Date(1560402514799l), 15f, 10, 2);
        Weather createdWeather = new Weather(1, "AC", new Date(1560402514799l), 15f, 10, 2);

        given(service.createWeather(weather)).willReturn(createdWeather);

        MvcResult result = mvc.perform(post("/weather")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(weather)))
        .andExpect(status().isOk())
                .andExpect(jsonPath("$['id']", is(createdWeather.getId())));

    }

这些测试适用于 GET 和 DELETE 方法。会不会是测试中给定的天气对象与控制器中创建的实际对象不匹配?

标签: javaspring-boottestingmockito

解决方案


您是在告诉 Mockito 您期望将确切的weather对象作为输入。

当您调用 mvc 时,尽管对象被转换为 JSON,然后被解析并最终Service作为与您传递给 Mockito 不同的实例传递给。

一种解决方案是使用通配符,如下所示:

given(service.createWeather(Mockito.any(Weather.class))).willReturn(createdWeather);

推荐阅读