Sam*_*nes 5 java spring json spring-mvc
我有一个小型 Spring MVC 项目。我正在为其编写 MockMvc 测试。它们中的大多数都可以工作,但是这个(我尝试使用纯 JSON 正文的第一个)给我带来了麻烦。我不断从 Spring 深处收到 NullPointerException 。我尝试通过它进行调试,但最终耗尽了附加的 Spring 源代码,而没有得到任何更接近的答案。
我的 JSON 块是从实时用户测试中捕获的,效果很好。但在测试中却抛出NPE。如果我将 JSON 块修改为格式错误(IE,在某处添加额外的逗号),那么它会按照预期抛出 400 Bad Request。删除多余的逗号,返回 NPE。使块无效(即,使域对象中标记为 @NotNull 的字段为 null)不会给出预期的 400 Bad Request。它只属于 NPE。
到目前为止,我的所有其他测试都是针对仅使用查询字符串参数的控制器,并且运行良好。另外,由于客户端的浏览器限制,我有一个必须将其 JSON 嵌入到 POST 参数中(IE,“json =”{blah:blah}”),我将其拉出并手动解析。这也很好用。
@RestController
public class SaveController {
@Autowired
private MyDao myDao;
@RequestMapping(value = "/path/to/controller", method = RequestMethod.POST)
@PreAuthorize("hasAnyRole('myRole', 'myAdminRole')")
public void updateThing(@Valid @RequestBody MyThing myThing) throws IOException {
myDao.updateMyThing(myThing);
}
}
Run Code Online (Sandbox Code Playgroud)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {TestDataAccessConfiguration.class, TestApplicationConfiguration.class})
public abstract class AbstractSpringTestCase {
@Autowired
protected WebApplicationContext wac;
protected MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
MockitoAnnotations.initMocks(this);
}
}
Run Code Online (Sandbox Code Playgroud)
public class SaveControllerTest extends AbstractSpringTestCase {
@Mock
private MyDao myDao;
@InjectMocks
@Autowired
private SaveController classUnderTest;
private static final JSON = "<a big JSON string captured from (working) production>";
@Test
public void testHappyPath() throws Exception {
mockMvc.perform(post("/path/to/controller")
.contentType(MediaType.APPLICATION_JSON)
.content(JSON))
.andExpect(status().isOk());
}
}
Run Code Online (Sandbox Code Playgroud)
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:170)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:137)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:145)
at SaveControllerTest.testHappyPath(SaveControllerTest.java)
Run Code Online (Sandbox Code Playgroud)
为了使用 Spring MockMvc 发送请求正文,您必须将 @RequestBody 对象映射为 json 字符串。
这是一个例子:
注册控制器:
@PostMapping("/signup")
public @ResponseBody
RealityKeeper createUser(@RequestBody SignupRequest signupRequest) {
System.out.println("SignupRequest: " + signupRequest);
String password = signupRequest.getPassword();
String username = signupRequest.getUsername();
String encoded = passwordEncoder.encode(password);
RealityKeeper realityKeeper = new RealityKeeper(username, encoded);
return repository.save(realityKeeper);
}
Run Code Online (Sandbox Code Playgroud)
注册控制器测试:
@Test
public void createUser() throws Exception {
SignupRequest signupRequest = new SignupRequest("foo", "bar");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();
String requestJson=ow.writeValueAsString(signupRequest);
mockMvc.perform(post("/api/signup")
.contentType(MediaType.APPLICATION_JSON)
.content(requestJson))
.andExpect(MockMvcResultMatchers.status().isOk());
}
Run Code Online (Sandbox Code Playgroud)
使用 Jackson 的对象映射器,您可以将 pojo 转换为 json 字符串并将其传递给 mockMvc content 方法。
希望这可以帮助
| 归档时间: |
|
| 查看次数: |
3199 次 |
| 最近记录: |