gpt4 book ai didi

spring - MocMVC 给出 HttpMessageNotReadableException

转载 作者:行者123 更新时间:2023-12-03 12:35:32 31 4
gpt4 key购买 nike

我仍在学习测试方法,我正在尝试让 MockMvc 测试为我工作。这是一个简单的 REST Controller ,此时仅使用帖子中 json 中的信息进行一些身份验证。我实际上已经实现了代码,所以我知道它正在工作,因为我得到了正确输入的正确响应和我放在一起的错误消息,两者都是 json 格式。我的问题是,即使实际代码有效,测试仍会因 HttpMessageNotReadableException 而失败,所以我假设我的测试设置不正确。你们能提供的任何帮助都会很棒。

这是我的 Controller

@Controller
public class RequestPaymentController {
protected final Log logger = LogFactory.getLog(getClass());
private PaymentService paymentService;
private LoginService loginService;

@Autowired
public void setPaymentService(PaymentService paymentService){
this.paymentService = paymentService;
}
@Autowired
public void setLoginService(LoginService loginService){
this.loginService = loginService;
}

@RequestMapping(value = "/requestpayment", method = RequestMethod.POST, headers="Accept=application/json")
@ResponseBody
public ResponseEntity<PaymentResult> handleRequestPayment(@RequestBody PaymentRequest paymentRequest, HttpServletRequest request, HttpServletResponse response, BindingResult result) throws Exception{
ResponseEntity<PaymentResult> responseEntity = null;
new LoginValidator().validate(paymentRequest, result);
boolean valid = loginService.isLoginValid(paymentRequest, result);
if (valid){
responseEntity = setValidResponse(paymentRequest);
}else {
throw new TumsException("exception message");

}
return responseEntity;
}


private ResponseEntity<PaymentResult> setValidResponse(PaymentRequest paymentRequest){
PaymentResult paymentResult = paymentService.getResults(paymentRequest);

return new ResponseEntity<PaymentResult>(paymentResult, HttpStatus.OK);
}


}

这是我的测试代码:
public class RequestPaymentControllerTest {

PaymentService mockPaymentService;
RequestPaymentController requestPaymentController;
HttpServletRequest mockHttpServletRequest;
HttpServletResponse mockHttpServletResponse;
PaymentRequest mockPaymentRequest;
BindingResult mockBindingResult;
LoginService mockLoginService;
PaymentResult mockPaymentResult;
MockMvc mockMvc;


@Before
public void setUp() throws Exception {
mockPaymentService = createMock(PaymentService.class);
mockHttpServletRequest = createMock(HttpServletRequest.class);
mockHttpServletResponse = createMock(HttpServletResponse.class);
mockPaymentRequest = createMock(PaymentRequest.class);
requestPaymentController = new RequestPaymentController();
mockBindingResult = createMock(BindingResult.class);
mockLoginService = createMock(LoginService.class);
requestPaymentController.setPaymentService(mockPaymentService);
mockPaymentResult = createMock(PaymentResult.class);
mockMvc = MockMvcBuilders.standaloneSetup(new RequestPaymentController()).build();

}

@After
public void tearDown() throws Exception {
mockPaymentService = null;
mockHttpServletRequest = null;
mockHttpServletResponse = null;
mockPaymentRequest = null;
requestPaymentController = null;
mockBindingResult = null;
mockLoginService = null;
mockPaymentResult = null;
mockMvc = null;
}


@Test
public void testHandleRequestPayment() throws Exception{
initializeStateForHandleRequestPayment();
createExpectationsForHandleRequestPayment();
replayAndVerifyExpectationsForHandleRequestPayment();

}



private void initializeStateForHandleRequestPayment(){

}

private void createExpectationsForHandleRequestPayment(){
mockPaymentRequest.getServiceUsername();
expectLastCall().andReturn("testuser");
mockPaymentRequest.getServicePassword();
expectLastCall().andReturn("password1!");
mockLoginService.isLoginValid(mockPaymentRequest,mockBindingResult);
expectLastCall().andReturn(true);
mockPaymentService.getResults(mockPaymentRequest);
expectLastCall().andReturn(mockPaymentResult);
}

private void replayAndVerifyExpectationsForHandleRequestPayment() throws Exception{
replay(mockPaymentService, mockBindingResult, mockHttpServletRequest, mockHttpServletResponse, mockPaymentRequest, mockLoginService);
requestPaymentController.setLoginService(mockLoginService);
requestPaymentController.handleRequestPayment(mockPaymentRequest, mockHttpServletRequest, mockHttpServletResponse, mockBindingResult);
mockMvc.perform(post("/requestpayment")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());
verify(mockPaymentService, mockBindingResult, mockHttpServletRequest, mockHttpServletResponse, mockPaymentRequest, mockLoginService);

}
}

andDo(print()) 的结果是:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /requestpayment
Parameters = {}
Headers = {Content-Type=[application/json], Accept=[application/json]}

Handler:
Type = portal.echecks.controller.RequestPaymentController
Method = public org.springframework.http.ResponseEntity<portal.echecks.model.PaymentResult> portal.echecks.controller.RequestPaymentController.handleRequestPayment(portal.echecks.model.PaymentRequest,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,org.springframework.validation.BindingResult) throws java.lang.Exception

Resolved Exception:
Type = org.springframework.http.converter.HttpMessageNotReadableException

ModelAndView:
View name = null
View = null
Model = null

FlashMap:

MockHttpServletResponse:
Status = 400
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []

Process finished with exit code 0

正如您所看到的,当我期望一个错误的请求状态时,测试通过了,但是我已经进行了日志记录并且我知道我发回的 ResponseBody 状态为 200。就像我说的,这是我第一次使用 MockMvc,所以我认为我没有设置正确的东西。有什么建议?

最佳答案

HttpMessageNotReadableException

Thrown by HttpMessageConverter implementations when the read method fails.



您还会在响应中收到 400 Bad Request。这应该都告诉您,您没有发送服务器期望的内容。您的服务器期望什么?
@RequestMapping(value = "/requestpayment", method = RequestMethod.POST, headers="Accept=application/json")
@ResponseBody
public ResponseEntity<PaymentResult> handleRequestPayment(@RequestBody PaymentRequest paymentRequest, HttpServletRequest request, HttpServletResponse response, BindingResult result) throws Exception{

这里的主要内容是 @RequestBody带注释的参数。所以你告诉你的服务器尝试反序列化 PaymentRequest HTTP POST 请求正文中的实例。

所以让我们看看你提出的请求
mockMvc.perform(post("/requestpayment")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());

我没有看到您为请求提供正文。应该有 content(String) 调用那里的某个地方来设置 POST 请求的内容。此内容应该是 PaymentRequest 的 JSON 序列化.

请注意,因为您使用的是 StandaloneMockMvcBuilder ,您可能需要设置 HttpMessageConverter实例自己,即。 MappingJackson2HttpMessageConverter序列化和反序列化 JSON。

请注意 BindingResult参数应紧跟在与其相关的参数之后。像这样
@RequestMapping(value = "/requestpayment", method = RequestMethod.POST, headers="Accept=application/json")
@ResponseBody
public ResponseEntity<PaymentResult> handleRequestPayment(@Valid @RequestBody PaymentRequest paymentRequest, BindingResult result, HttpServletRequest request, HttpServletResponse response) throws Exception{

不要忘记 @Valid .

请注意,这
requestPaymentController.setLoginService(mockLoginService);
requestPaymentController.handleRequestPayment(mockPaymentRequest, mockHttpServletRequest, mockHttpServletResponse, mockBindingResult);

MockMvc完全无关测试你在做什么。

关于spring - MocMVC 给出 HttpMessageNotReadableException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21648921/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com