web-dev-qa-db-ja.com

分離コントローラーテストはページング可能をインスタンス化できません

Spring-Dataのページネーションサポートを使用するSpring MVCコントローラーがあります:

@Controller
public class ModelController {

    private static final int DEFAULT_PAGE_SIZE = 50;

    @RequestMapping(value = "/models", method = RequestMethod.GET)
    public Page<Model> showModels(@PageableDefault(size = DEFAULT_PAGE_SIZE) Pageable pageable, @RequestParam(
            required = false) String modelKey) {

//..
        return models;
    }

}

そして、Nice Spring MVCテストサポートを使用してRequestMappingをテストしたいと思います。これらのテストを高速に保ち、他のすべてのものから隔離するために、完全なApplicationContextを作成したくありません。

public class ModelControllerWebTest {
    private MockMvc mockMvc;

    @Before
    public void setup() {
        ModelController controller = new ModelController();
        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @Test
    public void reactsOnGetRequest() throws Exception {
        mockMvc.perform(get("/models")).andExpect(status().isOk());
    }

}

このアプローチは、Pageableを必要としない他のコントローラーで正常に機能しますが、これを使用すると、これらの素敵な長いSpringスタックトレースの1つを取得できます。 Pageableをインスタンス化できないという不満があります。

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.data.domain.Pageable]: Specified class is an interface
at   
.... lots more lines

質問:魔法のNo-Request-Parameter-To-Pageable変換が適切に行われるようにテストを変更するにはどうすればよいですか?

注:実際のアプリケーションでは、すべてが正常に機能しています。

38
Jens Schauder

ページング可能に関する問題は、カスタム引数ハンドラーを提供することで解決できます。これが設定されている場合、ViewResolver例外(ループ)で実行されます。これを回避するには、ViewResolver(たとえば、匿名のJSON ViewResolverクラス)を設定する必要があります。

mockMvc = MockMvcBuilders.standaloneSetup(controller)
            .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
            .setViewResolvers(new ViewResolver() {
                @Override
                public View resolveViewName(String viewName, Locale locale) throws Exception {
                    return new MappingJackson2JsonView();
                }
            })
            .build();
43
meistermeier

テスト用に@EnableSpringDataWebSupportを追加するだけです。それでおしまい。

35
user2031839

スプリングブートの場合は、解決されたArgumentResolversを追加するだけです。

エラーをトリガーしたコードから:

this.mockMvc = MockMvcBuilders.standaloneSetup(weightGoalResource).build();

これには、うまくいきます:

this.mockMvc = MockMvcBuilders.standaloneSetup(weightGoalResource)
            .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
            .build();
9
groo

ちょうどこれに打ちのめされました。
私はこれに対する答えを提供したかった。

Pageable機能をテストしたくない場合は、省略してください。
Spring Boot 2.0.6でテスト済み:

コントローラのコード:

 @RequestMapping(value = "/searchbydistance/{distance}/{address}/page")
 public String searchByDistance(@PathVariable int distance, 
                                @PathVariable @NonNull String address, 
                                Model model, Pageable pageable, 
                                Locale locale, 
                                RedirectAttributes redirectAttributes) {
 }

テストコード:

 @Test
 @WithMockUser(username = "user", authorities = {"AdminRole"})
 public void testSearchByDistance() {

    try {
        UriComponents uri = UriComponentsBuilder.fromUriString("/joboffers/searchbydistance/{distance}/{address}/page").buildAndExpand(10, "Deggendorf");
        this.mockMvc.perform(get(uri.toUri())).andExpect(status().isOk());
    } catch (Exception e) {
        log.error(e.getMessage());
    }
}

お役に立てれば ...
敬具
トーマス

0
Thomas Lang