java - Spring Boot 单元测试 - 服务方法未被调用

标签 java spring-boot spring-boot-test

我是单元测试的新手。引用谷歌后,我创建了一个测试类来测试我的 Controller ,如下所示:

@RunWith(SpringRunner.class)
@WebMvcTest(PromoController.class)
public class PromoApplicationTests {
    @Autowired
    protected MockMvc mvc;
    @MockBean PromoService promoService;
   
   
   protected String mapToJson(Object obj) throws Exception {
      ObjectMapper objectMapper = new ObjectMapper();
      return objectMapper.writeValueAsString(obj);
   }
   protected <T> T mapFromJson(String json, Class<T> clazz)
      throws JsonParseException, JsonMappingException, IOException {
      
      ObjectMapper objectMapper = new ObjectMapper();
      return objectMapper.readValue(json, clazz);
   }
   
   @Test
    public void applyPromotionTest_1() throws Exception {
           String uri = "/classPath/methodPath";
           List<Cart> cartLs = new ArrayList<Cart>();
          // added few objects to the list
           
           String inputJson = mapToJson(cartLs);
           MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(uri)
              .contentType(MediaType.APPLICATION_JSON).content(inputJson)).andReturn();
           
           int status = mvcResult.getResponse().getStatus();
           assertEquals(200, status);
           String actual = mvcResult.getResponse().getContentAsString();
           String expected = "{\"key1\":val1, \"key2\":\"val 2\"}";
           assertEquals(expected, actual, true);
            
    }
}

我有以下 Controller 和服务类:

@RequestMapping("/classPath")
@RestController
public class PromoController {
    @Autowired
    PromoService promoService;
    
    @PostMapping("/methodPath")
    public PromoResponse applyPromo(@RequestBody List<Cart> cartObj) {
        PromoResponse p = promoService.myMethod(cartObj);
        return p;
    }
}

@Component
public class PromoServiceImpl implements PromoService{

    @Override
    public PromoResponse myMethod(List<Cart> cartList) {
        // myCode
    }

}

当我调试单元测试时, Controller 中的 p 对象为空。 我的状态为 200,但不是预期的 JSON 响应

我在这里错过了什么?

最佳答案

在使用 @WebMvcTest 时spring boot只会初始化web层,不会加载完整的应用上下文。在使用 @WebMvcTest 时,您需要使用 @MockBean 来创建和注入(inject) mock。

你做了什么

 @MockBean 
 PromoService promoService;

Spring Boot instantiates only the web layer rather than the whole context

We use @MockBean to create and inject a mock for the GreetingService (if you do not do so, the application context cannot start), and we set its expectations using Mockito.

但是,因为它是模拟 bean,所以您有责任模拟 myMethod() 调用

@Test
public void applyPromotionTest_1() throws Exception {
       String uri = "/classPath/methodPath";
       List<Cart> cartLs = new ArrayList<Cart>();
      // added few objects to the list

      // create PromoResponse object you like to return
      When(promoService.myMethod(ArgumentsMatchesr.anyList())).thenReturn(/*PromoResponse object */);
       
       String inputJson = mapToJson(cartLs);
       MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(uri)
          .contentType(MediaType.APPLICATION_JSON).content(inputJson)).andReturn();
       
       int status = mvcResult.getResponse().getStatus();
       assertEquals(200, status);
       String actual = mvcResult.getResponse().getContentAsString();
       String expected = "{\"key1\":val1, \"key2\":\"val 2\"}";
       assertEquals(expected, actual, true);
        
}

关于java - Spring Boot 单元测试 - 服务方法未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64048326/

相关文章:

java - 使用旋转组件在 3D 空间中转换光线

java - 连接特定组件字段类型的特定子类(@SpringBootApplication 和 @Autowire)

java - Spring Boot 安全性无效 requestURI

java - 在 Spring Boot 2 中将包含带引号的字符串的请求正文解析为 JSON

java - Spring Boot测试配置

mysql - 在 SpringBoot 中,使用默认值注释字段的正确方法是什么

java - 当我将 MainActivity 分成几个类时 Android 应用程序崩溃

java - 返回 String s 中 chars 中任何字符第一次出现的索引或 -1

java - 在java中使用ScriptEngine,如何提取函数列表?

java - 如何在@SpringBootTest 启动期间防止记录噪音?