package com.ankurm.hibernatedemo.validation; import static org.assertj.core.api.Assertions.assertThat; import jakarta.validation.ConstraintViolation; import jakarta.validation.Validator; import java.util.Set; import org.jboss.weld.environment.se.Weld; import org.jboss.weld.environment.se.WeldContainer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; /** * The other half of the measurement {@link PlainValidationNoCdiTest} started: run the identical * {@link StockLevel}/{@link PositiveInventoryValidator} pair inside a real, standalone CDI * container (Weld SE -- no Jakarta EE server) with {@code hibernate-validator-cdi} on the * classpath, and see whether {@code @Inject} actually works this time. * *

It does, and the mechanism is worth naming rather than treating as magic: {@code * hibernate-validator-cdi-9.1.3.Final.jar} registers {@code * org.hibernate.validator.cdi.ValidationExtension} as a {@code jakarta.enterprise.inject.spi.Extension} * (confirmed via its {@code META-INF/services/jakarta.enterprise.inject.spi.Extension} file). * Once Weld picks that extension up, it contributes CDI beans for {@code Validator}/{@code * ValidatorFactory} whose {@code ConstraintValidatorFactory} is {@code * org.hibernate.validator.cdi.spi.InjectingConstraintValidatorFactory} -- a factory that builds * each {@code ConstraintValidator} instance through the CDI {@code BeanManager} instead of plain * reflection, so {@code @Inject} fields on it are resolved like any other managed bean's. * *

Docs: docs/20-hibernate-validator-cdi.md */ class CdiValidationTest { private WeldContainer container; @AfterEach void tearDown() { if (container != null) { container.close(); } } @Test void constraintValidatorsInjectField_isProperlyPopulated_insideARunningCdiContainer() { container = new Weld().initialize(); Validator validator = container.select(Validator.class).get(); Set> belowThreshold = validator.validate(new StockLevel(3)); Set> atThreshold = validator.validate(new StockLevel(5)); Set> aboveThreshold = validator.validate(new StockLevel(10)); System.out.println("RESULT[cdi-validation-injection-works]: validator obtained from a running " + "Weld SE container | StockLevel(3) violations=" + belowThreshold.size() + " | StockLevel(5) violations=" + atThreshold.size() + " | StockLevel(10) violations=" + aboveThreshold.size() + " -- InventoryPolicy.minimumThreshold()=5 was actually injected and actually used, " + "no NullPointerException anywhere."); assertThat(belowThreshold) .as("3 is below the injected policy's threshold of 5 -- a real constraint violation, " + "not an exception") .hasSize(1); assertThat(atThreshold) .as("5 meets the threshold exactly") .isEmpty(); assertThat(aboveThreshold) .as("10 comfortably clears the threshold") .isEmpty(); assertThat(belowThreshold.iterator().next().getMessage()) .isEqualTo("quantity is below the minimum inventory threshold"); } }