Spring boot &引用;未找到返回值“的转换器”;在运行Spring Boot MockMvc测试时
我正在尝试创建一个Spring引导控制器的MockMvc测试。我特别不希望整个应用程序上下文被旋转起来,因此我将上下文限制在所讨论的控制器上。但是,测试失败,500的日志输出如下:Spring boot &引用;未找到返回值“的转换器”;在运行Spring Boot MockMvc测试时,spring-boot,kotlin,jackson,spring-boot-test,Spring Boot,Kotlin,Jackson,Spring Boot Test,我正在尝试创建一个Spring引导控制器的MockMvc测试。我特别不希望整个应用程序上下文被旋转起来,因此我将上下文限制在所讨论的控制器上。但是,测试失败,500的日志输出如下: 2020-03-03 13:04:06.904 WARN 8207 --- [ main] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNot
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]
Spring引导上下文似乎不知道如何找到Jackson
这是控制器
@RestController
class MyController {
@GetMapping("/endpoint")
fun endpoint(): ResponseDto {
return ResponseDto(data = "Some data")
}
}
data class ResponseDto(val data: String)
测试如下:
@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"
}
"""
)
)
}
}
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")
关于如何实现这一点有什么想法吗?我不确定,但我认为您需要指定输出的格式。大概是
@GetMapping(value = ["/endpoint"], produces = [MediaType.APPLICATION_JSON])
因此spring知道如何将其转换为json,而不是说XML或其他什么。解决方案是使用
@WebMvcTest
而不是@springbootest
来注释该类。这配置了足够的上下文,测试可以通过MockMvc
与控制器交互
不幸的是,启用@WebMvcTest
还有另一个副作用:配置中由@Bean
注释的方法指定的所有Bean也被实例化。当这些方法无法在测试环境中执行时(例如,因为它们访问某些环境变量),这是一个问题
为了解决这个问题,我将注释
@ActiveProfiles(“test”)
添加到测试中,并将@Profile(“!test”)
添加到每个这样的注释方法中。这会抑制对这些方法的调用,测试也会起作用。@EnableWebMvc
可能会解决您的问题。
根据Java文档:
将此注释添加到@Configuration
类将从WebMvcConfigurationSupport
导入Spring MVC配置
e.g.:
@Configuration
@EnableWebMvc
@ComponentScan(basePackageClasses = MyConfiguration.class)
public class MyConfiguration {
}
要自定义导入的配置,请实现接口WebMVCConfiguer并覆盖各个方法,例如:
@Configuration
@EnableWebMvc
@ComponentScan(basePackageClasses = MyConfiguration.class)
public class MyConfiguration implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
formatterRegistry.addConverter(new MyConverter());
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MyHttpMessageConverter());
}
}
@配置
@EnableWebMvc
@ComponentScan(basePackageClasses=MyConfiguration.class)
公共类MyConfiguration实现WebMVCConfiguer{
@凌驾
公共void addFormatters(FormatterRegistry FormatterRegistry){
addConverter(新的MyConverter());
}
@凌驾
public void configureMessageConverters(列表添加products=“application/json”
将错误更改为以下内容:org.springframework.web.HttpMediaTypeNotAcceptableException:找不到可接受的表示形式
端点在生产中工作正常,因此在测试中必须更改它是没有意义的。啊,我没有意识到这是一种特定于测试的情况。在这种情况下,问题就出现了可能是您的测试上下文中缺少了某些内容。我认为您正在尝试手动执行某些操作,以防止完整的上下文启动,spring boot已经支持该操作。请将测试上方的注释更改为@WebMvcTest(MyController.class)和autowire MockMvc,它应该可以执行您想要的操作(只是旋转web层,只有一个控制器),另请参见:(WebMvcTest在底部进行了详细说明。