MockMvc GET 请求失败,出现 404 但 URL 有效

Posted

技术标签:

【中文标题】MockMvc GET 请求失败,出现 404 但 URL 有效【英文标题】:MockMvc GET request failed with 404 but the URL is valid 【发布时间】:2022-01-05 02:01:59 【问题描述】:

我正在尝试使用 MockMvc 和 springmockk 库测试我的控制器,当我请求有效 URL 时,我收到 404 错误。 这是BadgeControllerImplTest

package uno.d1s.pulseq.controller

import com.ninjasquad.springmockk.MockkBean
import io.mockk.every
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.get
import uno.d1s.pulseq.controller.impl.BadgeControllerImpl
import uno.d1s.pulseq.core.constant.mapping.BadgeMappingConstants
import uno.d1s.pulseq.service.BadgeService

@WebMvcTest(useDefaultFilters = false, controllers = [BadgeControllerImpl::class])
class BadgeControllerImplTest 

    @Autowired
    private lateinit var mockMvc: MockMvc

    @MockkBean
    private lateinit var badgeService: BadgeService

    @BeforeEach
    fun setup() 
        every 
            badgeService.createBadge(any(), any(), any(), any(), any())
        .returns(byteArrayOf())
    

    @Test
    fun `should return the badge on getBadge`() 
        mockMvc.get(BadgeMappingConstants.GET_BADGE.replace("statisticId", "total-beats")) 
            param("color", "red")
            param("title", "Redefined title")
        .andExpect 
            status 
                isOk()
            
        
    

这是我要测试的代码:

package uno.d1s.pulseq.controller

import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RequestParam
import uno.d1s.pulseq.core.constant.mapping.BadgeMappingConstants
import javax.servlet.http.HttpServletResponse
import javax.validation.constraints.NotEmpty

interface BadgeController 

    @RequestMapping(
        BadgeMappingConstants.GET_BADGE,
        method = [RequestMethod.GET]
    )
    fun getBadge(
        @PathVariable statisticId: String,
        @RequestParam(required = false) color: String?,
        @RequestParam(required = false) title: String?,
        @RequestParam(required = false) style: String?,
        @RequestParam(required = false) logoUrl: String?,
        response: HttpServletResponse
    )

这个接口的实现是:

package uno.d1s.pulseq.controller.impl

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.RestController
import uno.d1s.pulseq.controller.BadgeController
import uno.d1s.pulseq.service.BadgeService
import javax.servlet.http.HttpServletResponse
import javax.validation.constraints.NotEmpty

@Validated
@RestController
class BadgeControllerImpl : BadgeController 

    @Autowired
    private lateinit var badgeService: BadgeService

    override fun getBadge(
        @NotEmpty statisticId: String,
        color: String?,
        title: String?,
        style: String?,
        logoUrl: String?,
        response: HttpServletResponse
    ) 
        response.run 
            contentType = "image/svg+xml"

            val badge = badgeService.createBadge(statisticId, color, title, style, logoUrl)
            writer.println(String(badge))
        
    

控制器映射到/api/badge/statisticId 谢谢。

【问题讨论】:

【参考方案1】:

我通过用@ContextConfiguration(classes = [BadgeControllerImpl::class]) 标记BadgeControllerImplTest 解决了这个问题

【讨论】:

以上是关于MockMvc GET 请求失败,出现 404 但 URL 有效的主要内容,如果未能解决你的问题,请参考以下文章

当普罗米修斯端点正在调用时,MockMvc 收到 404

没有 csrf 或无效 csrf 的 mockmvc 发布请求没有失败

file_get_contents - 无法打开流:HTTP 请求失败! HTTP/1.1 404 未找到

org.springframework.web.util.NestedServletException : 单元测试中的 MockMVC 请求处理失败

未捕获(承诺)错误:请求失败,状态码为404

MockMvc 响应返回 404,预期响应 201