4

MockMvc を使用して、非同期の結果で Spring 4.1 コントローラーをテストしようとしています。ここで説明したのと同じパターンに従いました。

https://github.com/spring-projects/spring-mvc-showcase/blob/master/src/test/java/org/springframework/samples/mvc/async/DeferredResultControllerTests.java

ただし、ここで説明するように戻り値ハンドラーを使用しているため、私のテストは異なります。

https://github.com/AndreasKl/spring-boot-mvc-completablefuture

私のテストコードは次のようになります。

public class MyControllerTest {

        private MockMvc mockMvc;
        private MyService myService;
        private MyController myController;

        public MappingJackson2HttpMessageConverter createMessageConverter() {

            ObjectMapper objectMapper = new ObjectMapper();
            List<MediaType> supportedMediaTypes = Arrays.asList(MediaTypes.JSON_V1);

            MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            converter.setObjectMapper(objectMapper);
            converter.setSupportedMediaTypes(supportedMediaTypes);

            return converter;
        }

        @Before
        public void setup() throws Exception {   

            MappingJackson2HttpMessageConverter converter = createMessageConverter();
            myService = mock(MyService.class);

            controller = new MyController(myService);

            mockMvc = MockMvcBuilders.standaloneSetup(controller)
                .setMessageConverters(converter)
                .setCustomReturnValueHandlers(new CompletableFutureReturnValueHandler())
                .build();
        }

        @Test
        public void test() throws Exception {

            String value = "foo";
            CompletableFuture<ExampleData> futureValue = 
                CompletableFuture.completedFuture(new ExampleData(value));

            when(myService.getExample()).thenReturn(futureValue);

            MvcResult mvcResult = mockMvc.perform(get("/example"))
                .andExpect(status().isOk())
                .andExpect(request().asyncStarted())
                .andExpect(request().asyncResult(instanceOf(ExampleData.class)))
                .andReturn();

            mockMvc.perform(asyncDispatch(mvcResult))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaTypes.JSON_V1_VALUE))
                .andExpect(jsonPath("$.property", is(value)));
        }
}

StandaloneMockMvcBuilder.setCustomReturnValueHandlers() を使用して戻り値ハンドラーを設定しても、呼び出されることはないようです。これにより、結果が Callable または DeferredResult ではないため、request().asyncStarted() のアサーションが失敗します。

ハンドラーを正しく設定していますか、それとも他に何か不足していますか?

==== ソリューション ======

ドキュメントを読み、デバッガーでステップスルーした後、setCustomReturnValueHandlers() がハンドラーをリストの最後に追加するのに対し、spring-boot-mvc-completablefuture の例ではそれを DeferredResult ハンドラーの前に挿入することがわかりました。非スタンドアロン モードを使用すると、これが可能になります。

4

0 に答える 0