【问题标题】:Spring boot - tests for servlet request/response, how to inject mock classes?Spring boot - 测试 servlet 请求/响应,如何注入模拟类?
【发布时间】:2017-11-15 07:38:15
【问题描述】:

我对 Spring Boot 还很陌生,并且将一个基本的微服务放在一起(它接受 Yelp 网址并为该餐厅抓取图像)。我认为现在是编写一些单元测试的好时机,但我遇到的一件事是将模拟类注入到我的 servlet 请求/响应测试中。

我要测试的代码很简单,看起来像这样。这基本上是我的服务的入口点,它接受 JSON 正文,从中提取 Yelp url,然后YelpRequestController.makeYelpRequest() 负责抓取图像并在 ArrayList 中返回图像链接。

@RestController
public class RequestController {

    @PostMapping(value = "/")
    public ArrayList<String> index(@RequestBody String reqBodyString) {

        //my own function to parse the json string
        HashMap<String, String> requestBody = parseReqBodyString(reqBodyString);
        String yelpURL = requestBody.get("yelpURL");

        YelpRequestController yelpRequest = new YelpRequestController(yelpURL);
        ArrayList<String> yelpImgLinks = yelpRequest.makeYelpRequest();
        return yelpImgLinks;
    }

}

这是我的单元测试代码。它基本上创建了一个 JSON 字符串并向我的 RequestController 发送请求,并确保响应正常。它现在通过了,但我希望测试只测试RequestController 而没有别的。目前它通过YelpRequestController 发送测试中的url 并开始抓取图像,这是我不想要的,因为我只想在这个测试中隔离RequestController。我一直在尝试模拟 YelpRequestController 类并返回结果,但我真的遇到了很多麻烦。

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class RequestControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void postRequestController() throws Exception {
        ObjectMapping jsonObject = new ObjectMapping();
        jsonObject.setYelpUrl("https://www.yelp.ca/biz/l-industrie-pizzeria-brooklyn");
        Gson gson = new Gson();
        String json = gson.toJson(jsonObject);
        mvc.perform(MockMvcRequestBuilders.post("/")
                .accept(MediaType.APPLICATION_JSON)
                .content(json))
                .andExpect(status().isOk());
    }
}

我一直在阅读有关如何使用 Mockito 的信息,并了解如何模拟另一个类并将其注入您正在测试的类中。但我真的很难在这里应用它。任何帮助将不胜感激。

【问题讨论】:

  • 使 YelpRequestController 成为一个 SPring bean。在您的 RequestController 中自动装配它。将 yelpURL 传递给 makeYelpRequest() 方法而不是构造函数,以使其成为无状态对象。然后您的单元测试可以将模拟 YelpRequestController 注入 RequestController。可测试性就是依赖注入。如果您使用new 自己创建依赖项,则无法注入模拟依赖项。
  • 啊,谢谢,我会考虑这样做的!

标签: java unit-testing spring-boot mockito spring-boot-test


【解决方案1】:

您好,希望我的回答对您有很大帮助。请看下面的简单,

@Autowired
private WebApplicationContext context;

private MockMvc mvc;

@Before
public void setUp() {
    this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}

在开始测试之前,您必须初始化 mvc。因此,您需要在测试前准备好您的应用程序。 SoringBoot

 private MockMvc mockMvc;

@InjectMocks
private UserController userController;

@Before
public void init(){
    MockitoAnnotations.initMocks(this);
    mockMvc = MockMvcBuilders
            .standaloneSetup(userController)
            .addFilters(new CORSFilter())
            .build();
}

SpringMVC 你需要注入你的控制器。

【讨论】:

    【解决方案2】:

    正如 cmets 中所指出的,您希望在控制器中使用依赖注入以使其可单独测试。 然后,您可以使用WebMvcTest 定位此特定控制器。与 SpringBootTest 相比,这不会加载您的完整 ApplicationContext

    这可能看起来像这样:

    @RestController
    public class RequestController {
    
        @Autowired
        private YelpRequestController yelpRequest;
    
        @PostMapping(value = "/")
        public ArrayList<String> index(@RequestBody String reqBodyString) {
    
            //my own function to parse the json string
            HashMap<String, String> requestBody = parseReqBodyString(reqBodyString);
            String yelpURL = requestBody.get("yelpURL");
    
            ArrayList<String> yelpImgLinks = yelpRequest.makeYelpRequest(yelpURL);
            return yelpImgLinks;
        }
    
    }
    

    在您的测试类中,您使用 @MockBean 注释要模拟的类,Spring 将自动将其用于 @Autowired 字段:

    @RunWith(SpringRunner.class)
    @WebMvcTest(RequestController.class)
    @AutoConfigureMockMvc
    public class RequestControllerTest {
    
        @Autowired
        private MockMvc mvc;
        @MockBean
        private YelpRequestController yelpRequest;
    
        @Test
        public void postRequestController() throws Exception {
            ObjectMapping jsonObject = new ObjectMapping();
            jsonObject.setYelpUrl("https://www.yelp.ca/biz/l-industrie-pizzeria-brooklyn");
            Gson gson = new Gson();
            String json = gson.toJson(jsonObject);
            mvc.perform(MockMvcRequestBuilders.post("/")
                    .accept(MediaType.APPLICATION_JSON)
                    .content(json))
                    .andExpect(status().isOk());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      • 2017-05-17
      • 2017-07-03
      • 1970-01-01
      • 2015-04-25
      • 2015-03-04
      • 2019-09-28
      相关资源
      最近更新 更多