You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot 2.6.1升级至3.5.4后MockMVC测试无法运行的问题求助

Spring Boot 2.6.1升级至3.5.4后MockMVC测试无法运行的问题求助

大家好,我最近在将项目从Spring Boot 2.6.1(Java 11)迁移到Spring Boot 3.5.4(Java 17)时,遇到了MockMVC测试无法正常运行的问题。我写了一个最小复现的测试案例,两种写法都抛出了异常,具体情况如下:


第一种测试写法:注入WebApplicationContext

我尝试通过构造方法注入WebApplicationContext来构建MockMVC,代码如下:

import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.context.WebApplicationContext

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SpringExtension::class)
class MyTest(
    @Autowired private val ctx: WebApplicationContext
) {
    @RestController
    class MyController {
        @GetMapping("/foo")
        fun foo() = "bar"
    }

    private lateinit var mockMvc: MockMvc

    @BeforeEach
    fun setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build()
    }

    @Test
    fun dbg() {
        println("Context ${ctx::class.qualifiedName}")
        println("mockmvc: ${ctx.getBeansOfType(MockMvc::class.java)}")
    }

    @Test
    fun foo() {
        mockMvc.perform(get("/foo"))
            .andExpect(status().isOk)
            .andExpect(content().string("bar"))
    }
}

运行后抛出的异常:

org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [org.springframework.web.context.WebApplicationContext ctx] in constructor [public com.example.MyTest(org.springframework.web.context.WebApplicationContext)]: No qualifying bean of type 'org.springframework.web.context.WebApplicationContext' available: expected at least 1 bean which qualifies as autowire candidate


第二种测试写法:直接注入MockMvc

后来我改用更贴近原本可用写法的方式,通过@AutoConfigureMockMvc直接注入MockMvc,代码如下:

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ExtendWith(SpringExtension::class)
class MyTest {
    @RestController
    class MyController {
        @GetMapping("/foo")
        fun foo() = "bar"
    }

    @Autowired
    private lateinit var mockMvc: MockMvc

    @Test
    fun foo() {
        mockMvc.perform(get("/foo"))
            .andExpect(status().isOk)
            .andExpect(content().string("bar"))
    }
}

这次抛出的异常是:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.MyTest': Unsatisfied dependency expressed through field 'mockMvc': No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

这个错误和我原本项目中测试代码抛出的错误完全一致。


我确认项目中已经引入了spring-boot-starter-web依赖:

implementation("org.springframework.boot:spring-boot-starter-web")

想请教下各位,我可能遗漏了什么配置或者依赖吗?麻烦帮忙分析下问题所在,谢谢!

内容来源于stack exchange

火山引擎 最新活动