Spring 引导应用程序在 mockmvc 测试中失败
Spring boot application fails on mockmvc test
我有一个简单的控制器测试,看起来像这样
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = CuponzaApiApplication.class)
@WebAppConfiguration
public class UserControllerTest {
private MockMvc mockMvc;
@Autowired
protected WebApplicationContext wac;
@Autowired
UserRepository userRepository;
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void createUser() throws Exception{
CuponzaUser user = new CuponzaUser("some@test.com", "firstName", "lastName");
ObjectWriter jackson = new ObjectMapper().writer().withDefaultPrettyPrinter();
mockMvc.perform(post("/user/add").content(jackson.writeValueAsString(user)).contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"));
}
但是它没有说出以下内容
java.lang.AssertionError: 未设置内容类型
这是我的控制器
@RestController
public class UserController {
@Autowired
UserRepository userRepository;
@RequestMapping(value = "/user/add",method = RequestMethod.POST,produces={MediaType.APPLICATION_JSON_VALUE})
public void AddUser(@RequestBody CuponzaUser user, HttpServletResponse response){
if(user ==null){
response.setStatus(HttpStatus.BAD_REQUEST.value());
return;
}else{
user.setCreationDate(new Date());
user.setLastSeenDate(new Date());
userRepository.save(user);
//response.addHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);
return;
}
}
我不想为每个响应手动添加内容类型 header,我认为 "produces" 注释应该处理这个问题
有什么想法吗?
这有点令人困惑 - @RequestMapping
注解的 produces
参数并没有真正修改响应 header,它是缩小适当处理程序方法范围的一种方法基于用户指定的 Accept
header。这样想,@RequestMapping
和所有与之关联的参数只是一种过滤到 Spring MVC 调用的适当方法的方法。
负责将响应转换为适当媒体类型的 MessageConverter
确实插入了响应 Content-Type
header,我认为你的问题是因为你没有设置模拟测试中的 Accept
header - .accept(MediaType.APPLICATION_JSON)
问题是您没有return任何东西。您的回复 body 为空。
在某种程度上是有道理的,没有内容,定义一个Content-Type
有什么意义?设置 Accept
header 也无济于事。此外,您也应该能够在单元测试之外重现相同的行为,也就是说,这不是您的单元 test/mock 设置的问题。
您可以:
- return一些内容
- 考虑 returning 204(无内容),如果你真的不想 return 任何东西(仍然不会给你
Content-Type
header 但它会明确表示没有内容)
- 手动添加 header,如您问题中注释掉的解决方法
我有一个简单的控制器测试,看起来像这样
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = CuponzaApiApplication.class)
@WebAppConfiguration
public class UserControllerTest {
private MockMvc mockMvc;
@Autowired
protected WebApplicationContext wac;
@Autowired
UserRepository userRepository;
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void createUser() throws Exception{
CuponzaUser user = new CuponzaUser("some@test.com", "firstName", "lastName");
ObjectWriter jackson = new ObjectMapper().writer().withDefaultPrettyPrinter();
mockMvc.perform(post("/user/add").content(jackson.writeValueAsString(user)).contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"));
}
但是它没有说出以下内容 java.lang.AssertionError: 未设置内容类型
这是我的控制器
@RestController
public class UserController {
@Autowired
UserRepository userRepository;
@RequestMapping(value = "/user/add",method = RequestMethod.POST,produces={MediaType.APPLICATION_JSON_VALUE})
public void AddUser(@RequestBody CuponzaUser user, HttpServletResponse response){
if(user ==null){
response.setStatus(HttpStatus.BAD_REQUEST.value());
return;
}else{
user.setCreationDate(new Date());
user.setLastSeenDate(new Date());
userRepository.save(user);
//response.addHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);
return;
}
}
我不想为每个响应手动添加内容类型 header,我认为 "produces" 注释应该处理这个问题
有什么想法吗?
这有点令人困惑 - @RequestMapping
注解的 produces
参数并没有真正修改响应 header,它是缩小适当处理程序方法范围的一种方法基于用户指定的 Accept
header。这样想,@RequestMapping
和所有与之关联的参数只是一种过滤到 Spring MVC 调用的适当方法的方法。
负责将响应转换为适当媒体类型的 MessageConverter
确实插入了响应 Content-Type
header,我认为你的问题是因为你没有设置模拟测试中的 Accept
header - .accept(MediaType.APPLICATION_JSON)
问题是您没有return任何东西。您的回复 body 为空。
在某种程度上是有道理的,没有内容,定义一个Content-Type
有什么意义?设置 Accept
header 也无济于事。此外,您也应该能够在单元测试之外重现相同的行为,也就是说,这不是您的单元 test/mock 设置的问题。
您可以:
- return一些内容
- 考虑 returning 204(无内容),如果你真的不想 return 任何东西(仍然不会给你
Content-Type
header 但它会明确表示没有内容) - 手动添加 header,如您问题中注释掉的解决方法