运行 Spring Boot MockMvc 测试时“未找到返回值的转换器”

use*_*350 4 jackson kotlin spring-boot spring-boot-test

我正在尝试创建 Spring Boot 控制器的 MockMvc 测试。我特别不希望启动整个应用程序上下文,因此我将上下文限制为有问题的控制器。但是,测试失败并显示 500,并显示以下日志输出:

2020-03-03 13:04:06.904  WARN 8207 --- [           main] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class main.endpoints.ResponseDto]
Run Code Online (Sandbox Code Playgroud)

看来 Spring Boot 上下文不知道如何找到 Jackson。

这是控制器

@RestController
class MyController {
    @GetMapping("/endpoint")
    fun endpoint(): ResponseDto {
        return ResponseDto(data = "Some data")
    }
}

data class ResponseDto(val data: String)
Run Code Online (Sandbox Code Playgroud)

测试如下:

@SpringBootTest(
    classes = [MyController::class],
    webEnvironment = SpringBootTest.WebEnvironment.MOCK
)
@AutoConfigureMockMvc
internal class MyControllerTest(@Autowired private val mockMvc: MockMvc) {
    @Test
    fun `should work`() {
        mockMvc.perform(MockMvcRequestBuilders.get("/endpoint").accept(MediaType.APPLICATION_JSON))
            .andExpect(
                content().json(
                    """
                        {
                            "data": "Some data"
                        }
                    """
                )
            )
    }
}
Run Code Online (Sandbox Code Playgroud)

build.gradle文件包含以下依赖项:

    def jacksonVersion = "2.10.2"
    testImplementation("com.fasterxml.jackson.core:jackson-core:2.10.2")
    testImplementation("com.fasterxml.jackson.core:jackson-databind:2.10.2")
    testImplementation("com.fasterxml.jackson.core:jackson-annotations:2.10.2")
Run Code Online (Sandbox Code Playgroud)

关于如何让它发挥作用有什么想法吗?

use*_*350 6

@WebMvcTest解决方案是使用而不是注释该类@SpringBootTest。这配置了足够的上下文,测试可以通过它MockMvc与控制器进行交互。

不幸的是,启用@WebMvcTest还有另一个副作用:@Bean配置中带注释的方法指定的所有 bean 也会被实例化。当这些方法无法在测试环境中执行时(例如,因为它们访问某些环境变量),这就是一个问题。

为了解决这个问题,我将注释添加@ActiveProfiles("test")到测试和@Profile("!test")每个这样的带注释的方法中。这会抑制这些方法的调用并且测试有效。