Spring MVC 测试 MockMvc - 如何配置 url 映射前缀

Spring MVC Test MockMvc - how do I configure a url mapping prefix

我有一个 DispatcherServlet,它有一个 URL 映射 /api1,随后还有一个控制器,它有一个控制器方法的映射 @GetMapping("/resource1")。所以基本上我有一个有效的 URL /api1/resource1 应该由提到的控制器处理。

此外,该设置包含一个 Spring 安全过滤器,它匹配请求 /*,因为它保护其他 URL 未被 Spring 处理(但例如 Jersey) . 由 Spring 安全过滤器保护的 API 设置为

    protected void configure(HttpSecurity http) throws Exception {
        //@formatter:off
        http.sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .requestMatchers()
                .antMatchers("/api1/**")
            .and()
            .authorizeRequests()
                .antMatchers("/**")
                .authenticated()

为了测试,我使用 MockMvc* 支持来设置模拟网络环境,包括 Spring 安全设置

mvc = MockMvcBuilders
                .webAppContextSetup(context)
                .apply(springSecurity())
                .build()

我想测试是否应用了安全检查,以及在安全检查成功时调用了控制器方法。

        when:
        def result = mvc.perform(
                get('/api1/resource1')
                    .header(HttpHeaders.AUTHORIZATION,  "Bearer " + apiToken))

        then:
          result.andExpect(status().isOk())

上面的代码基于带有 MockMvc 东西的 Spock 框架。 所有安全检查均已通过,因此 Spring 安全设置已完成,但最终应调用控制器但失败并显示 404 状态,即资源 - 这是映射的控制器方法 - 未找到。

我相信它会失败,因为模拟设置没有包含 /api 调度程序 servlet 映射。为了证明这个假设,我可以修改映射到 @GetMapping("/api1/resource1") 的控制器方法,测试将导致 HTTP OK (200)。

所以,我的问题是,是否可以在 MockMvc 设置中配置一种 URL 前缀? 有一个限制,代码库没有使用 Spring 引导(并且在未来一段时间内不能)!

编辑: 我将以下内容添加到我的测试中,让所有请求都设置 servletPath。

    static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVars) {
        new MockHttpServletRequestBuilder(HttpMethod.GET, urlTemplate, uriVars)
                .servletPath('/api1')
    }

我认为您只需要为请求配置 contextPath

详情见org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder.contextPath(String)