Java Spring REST文档测试中未使用自定义Jackson模块
我已经使用定制Jackson模块(使用SpringBoot1.3)在SpringREST文档上编写了一个小测试。在我的应用程序主类中,我只有Java Spring REST文档测试中未使用自定义Jackson模块,java,spring,spring-mvc,spring-boot,spring-restdocs,Java,Spring,Spring Mvc,Spring Boot,Spring Restdocs,我已经使用定制Jackson模块(使用SpringBoot1.3)在SpringREST文档上编写了一个小测试。在我的应用程序主类中,我只有@SpringBootApplication。然后我有另一个类JacksonCustomizations,看起来像这样: @Configuration public class JacksonCustomizations { @Bean public Module myCustomModule() { return new MyCustomModu
@SpringBootApplication
。然后我有另一个类JacksonCustomizations
,看起来像这样:
@Configuration
public class JacksonCustomizations {
@Bean
public Module myCustomModule() {
return new MyCustomModule();
}
static class MyCustomModule extends SimpleModule {
public MyCustomModule() {
addSerializer(ImmutableEntityId.class, new JsonSerializer<ImmutableEntityId>() {
@Override
public void serialize(ImmutableEntityId immutableEntityId, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeNumber( (Long)immutableEntityId.getId() );
}
});
}
}
}
@配置
公共类JacksonCustomizations{
@豆子
公共模块myCustomModule(){
返回新的MyCustomModule();
}
静态类MyCustomModule扩展了SimpleModule{
公共MyCustomModule(){
addSerializer(ImmutableEntityId.class,新的JsonSerializer(){
@凌驾
public void serialize(ImmutableEntityId ImmutableEntityId,JsonGenerator JsonGenerator,SerializerProvider SerializerProvider)引发IOException,JsonProcessingException{
jsonGenerator.WriteEnumber((长)immutableEntityId.getId());
}
});
}
}
}
这种定制非常完美。当我运行SpringBoot应用程序时,我看到了JSON应该是什么样子
但是,在我的文档测试中,没有应用定制。这是我的测试代码:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration
@WebAppConfiguration
public class NoteControllerDocumentation {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(documentationConfiguration(restDocumentation))
.build();
}
@Test
public void notesListExample() throws Exception {
mockMvc.perform(get("/api/notes/"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andDo(document("notes-list-example", responseFields(
fieldWithPath("[]").description("An array of <<note-example,note>>s."))));
}
@Configuration
@EnableWebMvc
@Import(JacksonCustomizations.class)
public static class TestConfiguration {
@Bean
public NoteController noteController() {
return new NoteController();
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@Spring应用程序配置
@WebAppConfiguration
公共类NoteControllerDocumentation{
@统治
公共最终RestDocumentation RestDocumentation=新的RestDocumentation(“目标/生成的代码段”);
@自动连线
私有WebApplicationContext上下文;
私有MockMvc-MockMvc;
@以前
public void setUp()引发异常{
mockMvc=MockMvcBuilders.webAppContextSetup(上下文)
.apply(文档配置(restDocumentation))
.build();
}
@试验
public void notesListExample()引发异常{
mockMvc.perform(get(“/api/notes/”)
.andExpect(状态().isOk())
.andExpect(content().contentType(MediaType.APPLICATION\u JSON\u UTF8))
.andDo(文档(“注释列表示例”),响应字段(
fieldWithPath(“[]”)。描述(“一个s数组”);
}
@配置
@EnableWebMvc
@导入(JacksonCustomizations.class)
公共静态类TestConfiguration{
@豆子
公共NoteController NoteController(){
返回新的NoteController();
}
}
}
注意我的测试中的应用程序上下文如何导入JacksonCustomizations
配置
我发现的其他东西:
- 在我的启动应用程序上添加
,将停止自定义李>@EnableWebMvc
- 在我的测试中删除
,将停止生成JSON@EnableWebMvc
NoteControllerDocumentation
未配置为使用Spring Boot创建应用程序上下文。这意味着Spring Boot的自动配置不会运行,因此,您的自定义Jackson模块不会应用于ObjectMapper
解决问题的最简单方法是删除TestConfiguration
类,并将SpringApplicationConfiguration
更新为referenceDemoApplication
。这将为您留下以下代码:
package com.example.controller;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentation;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.example.DemoApplication;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class)
@WebAppConfiguration
public class NoteControllerDocumentation {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(documentationConfiguration(restDocumentation))
.build();
}
@Test
public void notesListExample() throws Exception {
mockMvc.perform(get("/api/notes/"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().json("[{\"id\":1}]"))
.andDo(print())
.andDo(document("nodes-list-example", responseFields(
fieldWithPath("[]").description("An array of <<note-example,note>>s."))));
}
}
package com.example.controller;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentation;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.example.JacksonCustomizations;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration
@WebAppConfiguration
public class NoteControllerDocumentation {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(documentationConfiguration(restDocumentation))
.build();
}
@Test
public void notesListExample() throws Exception {
mockMvc.perform(get("/api/notes/"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().json("[{\"id\":1}]"))
.andDo(print())
.andDo(document("nodes-list-example", responseFields(
fieldWithPath("[]").description("An array of <<note-example,note>>s."))));
}
@Configuration
@EnableAutoConfiguration
@Import(JacksonCustomizations.class)
static class TestConfiguration {
@Bean
public NoteController notesController() {
return new NoteController();
}
}
}
您是否尝试将@Import(JacksonCustomizations.class)添加到NoteControllerDocumentation类中?@reos没有任何区别听起来Spring Boot没有用您的自定义
模块自动配置ObjectMapper
。这与您没有为应用程序提供类的SpringApplicationConfiguration
这一事实相匹配,因此springboot不知道该做什么。事实上,您共享的代码失败,出现了一个IllegalStateException
,该异常表示“在@SpringApplicationConfiguration中找不到配置类或位置”。您能否共享一个小样本项目,其中包含您正在运行的触发问题的确切代码?难道ContextConfiguration
不自动使用内部类Configuration
?请下载显示问题的示例项目。啊,不清楚TestConfiguration
是否是内部类(格式有点不正确)。感谢您的示例项目。我在下面发布了一个答案。但如果我的控制器使用自动连线服务或存储库呢?如何为它设置模拟?引用DemoApplication
将注入真正的服务/回购。您在问题中没有提到这一要求,因此我没有解决它。我已经用另一种方法的细节更新了我的答案。