0

我正在尝试使用 kotest 和 mockk 在 webmvc 中测试路由器功能。我认为它的编写方式应该只执行路由器功能和测试本身。其他一切都被嘲笑。路由器功能配置如下:

@Configuration
class DownloadRoutes(private val dnldCtrllr : DownloadController,
) {
    private var baseUrl : String = "download"

    @Bean
    fun router(): RouterFunction<ServerResponse> {
        return router {
            baseUrl.nest{
                accept(MediaType.TEXT_PLAIN).nest {
                    "/asset_request".nest {
                        POST(dnldCtrllr::downloadPost)
                    }
                }
            }
        }
    }
}

该测试使用 WebMvcTest 注释。我模拟了 POST 处理程序,因此如果在它的入口点调用它,它只会返回 OK 状态。

测试如下:

@WebMvcTest
@ContextConfiguration(classes = [DownloadRoutes::class])
class DownloadRoutesTest( @Autowired val mockMvc : MockMvc,
                          @MockkBean val mockDwnLd : DownloadController,
                          @Autowired val ctx : ApplicationContext
) : DescribeSpec({
    describe("Download Service Routes") {
        it("should route POSTs to the appropriate handler") {
            val bean = ctx.getBean("router")
            println(bean.toString())

            every { mockDwnLd.downloadPost(any())} returns ServerResponse.status(HttpStatus.OK).build()

            mockMvc.perform(MockMvcRequestBuilders
                            .post("/download/asset_request")
                            .accept(MediaType(MediaType.TEXT_PLAIN))
            )
                .andDo(MockMvcResultHandlers.print())       // prints the request and response; for debugging only
                .andExpect(MockMvcResultMatchers.status().isOk)
        }
    }
})

它没有通过。我已经打印了从应用程序上下文中获得的路由器 bean,以确保它在那里并且我认为它看起来是正确的。我还在 mockMvc 链中添加了一个打印,这样我就可以看到会发生什么。

这是打印:

/download => {
 Accept: text/plain => {
  /asset_request => {
   POST -> org.springframework.web.servlet.function.RouterFunctionDslKt$sam$org_springframework_web_servlet_function_HandlerFunction$0@1d9488b
   GET -> org.springframework.web.servlet.function.RouterFunctionDslKt$sam$org_springframework_web_servlet_function_HandlerFunction$0@dca44a2
  }
 }
}

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /download/asset_request
       Parameters = {}
          Headers = [Accept:"text/plain"]
             Body = null
    Session Attrs = {org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN=org.springframework.security.web.csrf.DefaultCsrfToken@3840636a}

Handler:
             Type = null


MockHttpServletResponse:
           Status = 403
    Error message = Forbidden
          Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Status expected:<200> but was:<403>
Expected :200
Actual   :403

我假设 403 意味着它永远不会进入路由器功能。“handler = null”是否意味着路由器没有被调用(为什么)?mockMvc 是否没有正确处理路由器功能(与旧的注释方法相反)?我假设是被模拟的 DownloadController 被注入到 DownloadRoutes 中,但我并不完全相信。

有人有什么想法吗?

4

1 回答 1

1

我应该更多地注意这是一个 403 错误。它并不是说它找不到路线。这是说我无法访问该路线。那是因为我为应用程序启用了安全性(我在依赖项列表中有“spring-boot-starter-security”)。我添加了

@AutoConfigureMockMvc(addFilters = false)

到注释。这可以防止添加安全过滤器并且测试现在通过了。 https://www.baeldung.com/spring-security-disable-profile可能是另一种选择。

于 2021-08-25T21:01:49.937 回答