2015-08-08 6 views
4

Как проверить/протестировать внутреннюю ошибку сервера 500 в MockMvc, когда мой контроллер имеет значение Тип серфинга Async?Spring MockMvc и код состояния HTTP контроллера async

Я пишу блок-тесты для моей конечной точки REST как часть тестовых случаев. Мне нужно проверить, что сервер отправляет 500 внутренних ошибок в качестве http-кода и с соответствующим сообщением об ошибке.

Вот мое основана весна загрузки приложение: (все импорт опущены для лучшей читаемости)

@RestController 
@RequestMapping("/user") 
@EnableAutoConfiguration 
@SpringBootApplication 
public class App 
{ 
    @RequestMapping(method = RequestMethod.GET, value = "/{name}", 
      produces = MediaType.APPLICATION_JSON_VALUE) 
    private DeferredResult<String> greetByJson(@PathVariable("name") final String name){ 
     DeferredResult<String> dResult = new DeferredResult<String>(); 

     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Thread.sleep(5000); 
        dResult.setErrorResult(new RuntimeException("Boom!!! time for Internal server error")); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 

     return dResult; 
    } 

    public static void main(String[] args) 
    { 
     SpringApplication.run(App.class); 
    } 
} 

Вот мой MovkMvc JUnit тесты:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = MockServletContext.class) 
@WebAppConfiguration 
public class AppTest { 

    private final MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new App()) 
      .build(); 

    @Test 
    public void testAsyncInternalServerError() { 
     try { 
      MvcResult mvcResult = mockMvc.perform(
        get("/user/naveen").accept(MediaType.APPLICATION_JSON_VALUE)) 
        .andExpect(request().asyncStarted()) 
        .andReturn(); 

      System.out.println("Http Response Content = " + mvcResult.getAsyncResult()); 
      System.out.println("Http Response Status Code = " + mvcResult.getResponse().getStatus()); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Ниже Вы консоль печатает:

2015-08-08 18:11:51.494 INFO 10224 --- [   main] o.s.w.c.s.GenericWebApplicationContext : Refreshing org.s[email protected]a82c5f1: startup date [Sat Aug 08 18:11:51 IST 2015]; root of context hierarchy 
2015-08-08 18:11:51.526 INFO 10224 --- [   main] o.e.j.i.junit.runner.RemoteTestRunner : Started RemoteTestRunner in 0.258 seconds (JVM running for 1.131) 
Http Response Content = java.lang.RuntimeException: Boom!!! time for Internal server error 
Http Response Status Code = 200 
2015-08-08 18:11:56.584 INFO 10224 --- [  Thread-1] o.s.w.c.s.GenericWebApplicationContext : Closing org.s[email protected]a82c5f1: startup date [Sat Aug 08 18:11:51 IST 2015]; root of context hierarchy 

Из приведенного выше журнала видно, что Moc kMvc возвращает код статуса http как 200 не 500. Сообщение об ошибке просто отлично.

Где, как, когда я ссылаться на конечную точку с помощью Chrome почтальона, я вижу 500 внутренняя ошибка сервера, прилагаемая в образе enter image description here

+0

Вы действительно должны принять @mzc ответ «s. :) – growlingchaos

ответ

8

Вы должны выполнить асинхронную отправку и проверить состояние после:

@Test 
public void testMethod() throws Exception { 

    MvcResult mvcResult = mockMvc.perform(get("/your/endpoint")) 
      .andExpect(request().asyncStarted()) 
      .andExpect(request().asyncResult(notNullValue())) 
      .andReturn(); 

    mockMvc.perform(asyncDispatch(mvcResult)) 
      .andExpect(status().isInternalServerError()) 
      .andReturn(); 

} 
+0

Спасибо @mzc, это сработало ... спасибо за быструю помощь .... –

+0

Полный пример кода? – powder366

1

Пользовательский perform вспомогательного метода, который обрабатывает синхронизацию и асинхронный запрос как:

ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception { 
    ResultActions resultActions = mockMvc.perform(builder); 
    if (resultActions.andReturn().getRequest().isAsyncStarted()) { 
     return mockMvc.perform(asyncDispatch(resultActions 
      .andExpect(request().asyncResult(anything())) 
      .andReturn())); 
    } else { 
     return resultActions; 
    } 
} 

Longer answer with example here

0

Ниже приведен пример работает (Groovy Спок спецификация), с помощью метода asyncPerform(builder)

import static org.hamcrest.core.IsNull.notNullValue 
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch 
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post 
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.* 

@ContextConfiguration(classes = [MyConfig]) 
@WebAppConfiguration 
class MyControllerComponentSpec extends Specification { 

    @Autowired 
    WebApplicationContext webApplicationContext 

    MockMvc endpoint 

    def setup() { 
     endpoint = MockMvcBuilders.webAppContextSetup(webApplicationContext).build() 
    } 

    ResultActions asyncPerform(MockHttpServletRequestBuilder builder) throws Exception { 
     ResultActions resultActions = endpoint.perform(builder); 
     asyncDispatch(resultActions.andExpect(request() 
         .asyncResult(notNullValue())) 
         .andReturn())); 
    } 

    def "accepts valid request and responds with 200 status code and response body"() { 
     when: 
     def response = asyncPerform(post("/my_async_endpoint") 
      .content("""{"correlationID": "fe5d1699-20e3-4502-bf51-b947e6b9e51a"}""") 
      .header("Content-Type", "application/json")) 
      .andDo(print()) 

     then: 
     response.andExpect(status().is(200)) 
      .andExpect(jsonPath("body.correlationID").value("fe5d1699-20e3-4502-bf51-b947e6b9e51a")) 

    } 
}