модульное тестирование класса контроллера, имеющего шаблон rest

#spring-boot #junit #mockito #resttemplate

#spring-boot #junit #mockito #resttemplate

Вопрос:

Я пробовал тестировать класс контроллера, он не является макетом шаблона rest, который находится в классе контроллера.

 @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 внутри класса контроллера с шаблоном rest, поэтому я издевался над шаблоном rest, который имеет значение null, и функция assert также не работает.Когда я использую синтаксис проверки для 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 для тестирования уровень контроллера. Он настроит a MockMvc для вас таким образом, чтобы вы могли использовать его для определения HTTP-запроса, который вы хотите отправить контроллеру, а затем проверить, соответствует ли возвращенный HTTP-ответ ожидаемому.

Обратитесь к этому для получения более подробной информации о том, как это сделать .

Комментарии:

1. Использовал макет mvc, но столкнулся с ошибкой, из-за которой я пропустил логику

2. не могли бы вы, пожалуйста, отредактировать вопрос, а не публиковать новый ответ, который на самом деле не является ответом, пожалуйста?