cof*_*ava 7 spring unit-testing spring-mvc
我还在学习测试的方法,我正在尝试让MockMvc测试为我工作.这是一个简单的REST控制器,此时只使用帖子中json的信息进行一些身份验证.我实际上已经实现了代码,所以我知道它正在工作,因为我用正确的输入和我放在一起的错误消息都以json格式返回正确的响应.我的问题是测试使用HttpMessageNotReadableException失败,即使实际代码有效,所以我假设我没有正确设置我的测试.你们给予的任何帮助都会很棒.
这是我的控制器
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试代码:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,当我期待一个糟糕的请求状态时,测试通过,但我已经输入了日志记录,我知道我发回的ResponseBody有200状态.就像我说的,这是我第一次使用MockMvc,所以我认为我没有正确设置.有什么建议?
Sot*_*lis 13
一个HttpMessageNotReadableException
是
当read方法失败时,由HttpMessageConverter实现抛出.
您的回复中还会收到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{
Run Code Online (Sandbox Code Playgroud)
这里的主要内容是带@RequestBody
注释的参数.因此,您要告诉服务器尝试PaymentRequest
从HTTP POST请求的主体反序列化实例.
那么让我们看看你正在提出的要求
mockMvc.perform(post("/requestpayment")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest());
Run Code Online (Sandbox Code Playgroud)
我没有看到你为请求提供正文.应该content(String)
在那里的某个地方设置呼叫来设置POST请求的内容.这个内容应该是一个JSON序列化PaymentRequest
.
请注意,因为您正在使用StandaloneMockMvcBuilder
,您可能需要自己设置HttpMessageConverter
实例,即.a 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{
Run Code Online (Sandbox Code Playgroud)
别忘了@Valid
.
请注意这一点
requestPaymentController.setLoginService(mockLoginService);
requestPaymentController.handleRequestPayment(mockPaymentRequest, mockHttpServletRequest, mockHttpServletResponse, mockBindingResult);
Run Code Online (Sandbox Code Playgroud)
与MockMvc
您正在进行的测试完全无关.
归档时间: |
|
查看次数: |
8179 次 |
最近记录: |