尝试像这样测试结构:
@RequestMapping(value = "/test", method = POST)
public ResponseEntity test(@RequestBody TestRequest request, Errors errors) {
testValidator.validate(request, errors); // Spring Validator interface impl
if (errors.hasErrors())
return new ResponseEntity(HttpStatus.BAD_REQUEST);
return new ResponseEntity(HttpStatus.OK);
}
Errors
对象是由框架而不是我传递的,所以除了使用像Mockito这样的东西之外,没有更好的方法来改变它的测试行为。 {1}}:
Answer
...但问题是@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ExampleTest {
@Autowired
private TestRestTemplate testRestTemplate;
@MockBean
private TestValidator testValidator;
@Test
public void test() {
doAnswer(new Answer<Errors>() {
@Override
public Errors answer(InvocationOnMock invocation) throws Throwable {
Errors errors = spy((Errors) invocation.getArguments()[1]);
//errors.rejectValue("id", "id", "id rejected");
doReturn(true).when(errors).hasErrors();
return errors;
}
}).when(testValidator).validate(any(), any());
ResponseEntity re = testRestTemplate
.postForEntity("/test", new TestRequest(213L), String.class);
assertEquals(HttpStatus.BAD_REQUEST, re.getStatusCode());
}
仍然返回errors.hasErrors()
,尽管在false
测试块上,由于HTTP状态doAnswer
,断言失败。我希望OK
对象在Errors
调用后立即成为具有指定行为的间谍,但似乎我做错了。
那么,如何使用Mockito .validate()
返回自定义对象?
答案 0 :(得分:2)
不要在测试中使用postForEntity
,因为这使它成为框架本身的集成测试,加上您正在测试的实际类。
只需创建自己的Errors
对象,这可能是也可能不是模拟对象。如果它是模拟,那么你可以按如下方式设置它。
doReturn(true).when(mockErrors).hasErrors();
然后你的测试看起来像这样。
@Test
public void test() {
ResponseEntity re = objectThatYoureTesting.test(mockTestRequest, mockErrors);
assertEquals(HttpStatus.BAD_REQUEST, re.getStatusCode());
}
答案 1 :(得分:1)
doReturn(true).when(errors).hasErrors()
实例时, errors
才有效。如果将返回的Error
引用分配给变量,则mock应该起作用:
errors = testValidator.validate(request, errors);
您将添加此作业仅用于测试目的,但它也有利于代码可读性;它强烈表示在errors
方法中修改了validate
实例。
更新:您可以包装验证程序以返回错误,而不是侦察包装的验证程序:
public class ValidatorWrapper {
public Errors validate(TestRequest request, Errors errors) {
testValidator.validate(request, errors);
return errors;
}
}
测试代码类似于:
controller.setValidatorWrapper(spiedValidatorWrapper);
doAnswer(new Answer<Errors>() {
@Override
public Errors answer(InvocationOnMock invocation) throws Throwable {
Errors errors = spy((Errors) invocation.getArguments()[1]);
//errors.rejectValue("id", "id", "id rejected");
doReturn(true).when(errors).hasErrors();
return errors;
}
}).when(spiedValidatorWrapper).validate(any(), any());
//rest of the test
这应该可以解决问题。