adam bien's blog

Time travelling with Bean Validation 2.0 and Java EE 8 📎

With Java EE 8 and Bean Validation 2.0 JSR-380 you can time travel by passing an adjusted java.time.Clock instance to the clockProvider method:


import java.time.Clock;
import java.time.Duration;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
(...)

public class BeanValidationTest {

private Validator validator;

@Before
public void init() {
    ValidatorFactory factory = Validation
            .byDefaultProvider()
            .configure()
            .clockProvider(this::configureClockWithFutureTime)
            .buildValidatorFactory();
    this.validator = factory.getValidator();
}

Clock configureClockWithFutureTime() {
    return Clock.offset(Clock.systemDefaultZone(), Duration.ofSeconds(10));
}


Now you can configure whether your vacations are already over:

        
import java.util.Date;
import javax.validation.constraints.PastOrPresent;

public class Vacations {

    @PastOrPresent
    private Date date;

    public Vacations() {
        this.date = new Date();
    }
}


@Test
public void vacationsAreOver() {
    Set<ConstraintViolation<Vacations>> violations = this.validator.validate(new Vacations());
    assertTrue(violations.isEmpty());
}

...or whether you have to work again:


import java.util.Date;
import javax.validation.constraints.Future;

public class Development {

    @Future
    private Date date;
    public Development() {
        this.date = new Date();
    }
}
//....
@Test
public void weAreWorkingNow() {
    Set<ConstraintViolation<Development>> violations = this.validator.validate(new Development());
    boolean rightMessage = violations.stream().
            map(violation -> violation.getMessage()).
            allMatch(message -> "must be a future date".equalsIgnoreCase(message));
    assertTrue(rightMessage);
    assertFalse(violations.isEmpty());
}

}

To run the bean validation as a JUnit test, you will need the following dependencies:


<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.5.Final</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.0</version>
    <scope>test</scope>
</dependency>

See you at Java EE 8 on Java 9, at Munich Airport, Terminal 2