具有剩余模板的控制器类的单元测试

Posted

技术标签:

【中文标题】具有剩余模板的控制器类的单元测试【英文标题】:unit testing of controller class which has rest template 【发布时间】:2022-01-16 03:03:06 【问题描述】:

我已经尝试在控制器类上进行测试,它不是模拟控制器类中的其余模板。

@RestController
public class LoginController 

    @RequestMapping(value = "api/v1/login", method = RequestMethod.POST)
    public String Loginpostmethod(@RequestBody LoginUser login) 

        String url = "https://jira2.domain.com/rest/auth/1/session";
        String username = login.getUsername();
        String password = login.getPassword();
        String authStr = username + ":" + password;
        String base64Creds = Base64.getEncoder().encodeToString(authStr.getBytes());
        HashMap<String, String> map = new HashMap<>();
        map.put("username", username);
        map.put("password", password);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + base64Creds);
        headers.set("Content-Type", "application/json");
        headers.set("Accept", "application/json");
        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<HashMap<String, String>> entity = new HttpEntity<>(map, headers);
        
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        return response.getBody();
        
        

控制器测试类

public class LoginControllerTest 
    
    @Mock
    RestTemplate mockrestTemplate;
    private String testUrl = "https://jira2.domain.com/rest/auth/1/session";
    
    @MockBean
    LoginUser mocklogin;
    
    @InjectMocks
    LoginController loginController;
    
    @Test
    public void TestPostMethodSuccess() throws  Exception
        LoginUser mocklogin=new LoginUser();
        mocklogin.setUsername("testusername");
        mocklogin.setPassword("testpassword");
        
        
        HashMap<String, String> map = new HashMap<>();  
        map.put("username", "username");
        map.put("password", "password");
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic");
        headers.set("Content-Type", "application/json");
        headers.set("Accept", "application/json");
        
        HttpEntity<?> request = new HttpEntity<>(map, headers);

        ResponseEntity<String> response = new ResponseEntity<>("respons",HttpStatus.OK);
        
        
        Mockito.when(mockrestTemplate.exchange(testUrl, HttpMethod.POST, request, String.class)).thenReturn(response);
   
        assertEquals(200,response.getStatusCodeValue());
        loginController.Loginpostmethod(mocklogin);
    
    

我所做的是这是测试控制器类的正确方法,它应该调用控制器类中的 api 有一个休息模板,所以我已经模拟了具有空值和断言功能的休息模板不工作。当我对 when 和 then 使用验证语法时,错误是想要的但没有被调用。


使用模拟 Mvc,

 @RunWith(SpringJUnit4ClassRunner.class)
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class LoginControllerTest 
    
    @Autowired
    private MockMvc mockMvc;
    
    @Mock
    LoginUser mocklogin;
    
    @InjectMocks
    LoginController loginController;
    
    @Test
    public void TestPostMethodSuccess() throws  Exception
        LoginUser mocklogin=new LoginUser();
        mocklogin.setUsername("testusername");
        mocklogin.setPassword("testpassword");
        
        this.mockMvc.perform(MockMvcRequestBuilders
                .post("/api/v1/login")
                .contentType(MediaType.APPLICATION_JSON)
                .content(asJsonString(mocklogin))
                .accept(MediaType.APPLICATION_JSON))
                .andDo(print())
                .andExpect(MockMvcResultMatchers.status().isOk());
            
        
    public static String asJsonString(final Object obj) 
        try 
            final ObjectMapper mapper = new ObjectMapper();
            final String jsonContent = mapper.writeValueAsString(obj);
            System.out.println(jsonContent);
            return jsonContent;
         catch (Exception e) 
            throw new RuntimeException(e);
        
    

    

面对错误,

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://jira2.domain.com/rest/auth/1/session": jira2.domain.com; nested exception is java.net.UnknownHostException: jira2.domain.com
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)

【问题讨论】:

【参考方案1】:

你必须使用@WebMvcTest来测试控制器层。它将为您配置一个MockMvc,以便您可以使用它来定义要发送到控制器的 HTTP 请求,然后验证返回的 HTTP 响应是否符合您的预期。

请参阅this 了解更多详情。

【讨论】:

使用了模拟 mvc 但面临我错过逻辑的错误 请您编辑问题而不是发布一个不是真正答案的新答案吗?

以上是关于具有剩余模板的控制器类的单元测试的主要内容,如果未能解决你的问题,请参考以下文章

如何在单元测试期间通过 Thymeleaf 模板的身份验证

如何在单元测试期间为Thymeleaf模板传递身份验证

springMVCRestTemplate控制层单元测试

具有多个模块和多个主类的spring boot项目-单元测试失败

用于单元测试的模拟休息模板

使用 Karma Jasmine 的 Angular 1.5 组件模板单元测试