Autowiring does not work inside custom constraint validator using Spring-Test-MVC
Dear Spring Community,
I have an issue with autowiring inside a custom constraint validator when running an integration test using spring-test-mvc. The service I require is null.
However when I run the web app, its is auotwired correctly.
Custom Constraint Validator (Booking Service is null!)
Code:
public class CheckAvailabilityValidator implements ConstraintValidator<CheckAvailability, Booking> {
private DateTimeFormatter formatter;
private int maxNumberOfBookings = 2;
@Autowired
private BookingService bookingService;
public void initialize(CheckAvailability constraintAnnotation) {
formatter = DateTimeFormat.forPattern("dd/MM/yyyy");
}
public boolean isValid(Booking booking, ConstraintValidatorContext constraintContext) {
if (booking.getArrivalDate() == null || booking.getDepartureDate() == null) {
return false;
}
DateTime arrivalDate = formatter.parseDateTime(booking.getArrivalDate());
DateTime departureDate = formatter.parseDateTime(booking.getDepartureDate());
if (bookingService.findBookingsByDateRange(arrivalDate,departureDate).size() > maxNumberOfBookings) {
return false;
} else {
return true;
}
}
}
Annotation
Code:
@Target({ TYPE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = CheckAvailabilityValidator.class)
@Documented
public @interface CheckAvailability {
String message() default "{we.do.not.have.availability}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Service
Code:
@Service
public class BookingService implements IBookingService{
@Autowired
private BookingDao bookingDao;
private static Logger logger = LoggerFactory.getLogger(BookingService.class);
@Override
public List<Booking> findBookingsByDateRange(DateTime from, DateTime to) {
return bookingDao.findBookingsByDateRange(from, to);
}
}
Unit Test
Code:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {BookingControllerConfig.class})
public class BookingControllerTest {
@Autowired
private BookingController bookingController;
private List<Booking> bookingList = new ArrayList<Booking>();
.....
@Test
public void testPostBookingDetails() throws Exception {
standaloneSetup(bookingController).build().perform(post("/booking_details")
.param("arrivalDate", "01/01/2013")
.param("departureDate", "09/01/2013")
.param("accomendationType", "Suite")
.param("numberOfAdults", "2")
.param("numberOfChildren", "2"))
.andDo(print())
.andExpect(status().isOk());
}
...
}
Config
Code:
@Configuration
public class BookingControllerConfig {
@Bean
public BookingController bookingController() {
return new BookingController();
}
@Bean
public BookingService bookingService() {
return Mockito.mock(BookingService.class);
}
.....
}
Controller
Code:
@Controller
public class BookingController {
...
@RequestMapping(value = "/booking_details", method = RequestMethod.POST)
public ModelAndView showBookingDetails(@Validated Booking booking, BindingResult bindingResult, ContactDetails
contactDetails, HttpServletResponse response) throws IOException {
...
}
...
}
Any ideas?