I have the following unit test:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {EqualblogApplication.class})
@WebAppConfiguration
@TestPropertySource("classpath:application-test.properties")
public class PostServiceTest {
// ...
@Test(expected = ConstraintViolationException.class)
public void testInvalidTitle() {
postService.save(new Post()); // no title
}
}
The code for save
in PostService
is:
public Post save(@Valid Post post) {
return postRepository.save(post);
}
The Post
class is marked with @NotNull
in most fields.
The problem is: no validation exception is thrown.
However, this happens only in testing. Using the application normally runs the validation and throws the exception.
Note: I would like to do it automatically (on save) and not by manually validating and then saving (since it's more realistic).
Annotation Type Test. The Test annotation tells JUnit that the public void method to which it is attached can be run as a test case. To run the method, JUnit first constructs a fresh instance of the class then invokes the annotated method. Any exceptions thrown by the test will be reported by JUnit as a failure.
The @Valid annotation is a key feature of Bean Validation, as it allows to validate object graphs with a single call to the validator. To make use of it all fields that should be recursively checked should be annotated with @Valid .
The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.
This solution works with Spring 5. It should work with Spring 4 as well. (I've tested it on Spring 5 and SpringBoot 2.0.0).
There are three things that have to be there:
Like this:
@TestConfiguration
static class TestContextConfiguration {
@Bean
public MethodValidationPostProcessor bean() {
return new MethodValidationPostProcessor();
}
}
Like this:
@Validated
class PostService {
public Post save(@Valid Post post) {
return postRepository.save(post);
}
}
More details in MethodValidationPostProcessor documentation
Hope that helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With