Я использую Spring 4.16, и у меня есть свой ValidationAspect, который проверяет аргументы методов и выдает исключение ValidationException, если что-то не так. Это вызывается, когда я запускаю сервер и отправляю запросы, но не когда приходит из теста:
package com.example.movies.domain.aspect;
...
@Aspect
public class ValidationAspect {
private final Validator validator;
public ValidationAspect(final Validator validator) {
this.validator = validator;
}
@Pointcut("execution(* com.example.movies.domain.feature..*.*(..))")
private void selectAllFeatureMethods() {
}
@Pointcut("bean(*Service)")
private void selectAllServiceBeanMethods() {
}
@Before("selectAllFeatureMethods() && selectAllServiceBeanMethods()")
public synchronized void validate(JoinPoint joinPoint) {
// Validates method arguments which are annotated with @Valid
}
}
Конфигурационный файл, в котором я создаю аспект bean-компонента
package com.example.movies.domain.config;
...
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AspectsConfiguration {
@Bean
@Description("Hibernate validator. Used to validate request's input")
public Validator validator() {
ValidatorFactory validationFactory = Validation.buildDefaultValidatorFactory();
return validationFactory.getValidator();
}
@Bean
@Description("Method validation aspect")
public ValidationAspect validationAspect() {
return new ValidationAspect(this.validator());
}
}
Итак, это тест, он должен генерировать исключение ValidationException непосредственно перед тем, как попасть в метод addSoftware, поскольку это недопустимый объект softwareObject.
@ContextConfiguration
@ComponentScan(basePackages = {"com.example.movies.domain"})
public class SoftwareServiceTests {
private static final Logger LOGGER = LoggerFactory.getLogger(SoftwareServiceTests.class.getName());
private SoftwareService softwareService;
@Mock
private SoftwareDAO dao;
@Mock
private MapperFacade mapper;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
this.softwareService = new SoftwareServiceImpl(this.dao);
((SoftwareServiceImpl) this.softwareService).setMapper(this.mapper);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SoftwareServiceTests.class);
ctx.getBeanFactory().registerSingleton("mockedSoftwareService", this.softwareService);
this.softwareService = (SoftwareService) ctx.getBean("mockedSoftwareService");
}
@Test(expected = ValidationException.class)
public void testAddInvalidSoftware() throws ValidationException {
LOGGER.info("Testing add invalid software");
SoftwareObject softwareObject = new SoftwareObject();
softwareObject.setName(null);
softwareObject.setType(null);
this.softwareService.addSoftware(softwareObject); // Is getting inside the method without beeing validated so doesn't throws ValidationException and test fails
}
}
Если я запускаю службу и добавляю этого недопустимого пользователя из почтового запроса, это вызывает исключение ValidationException, как и должно быть. Но по какой-то причине он никогда не выполняет метод ValidationAspect из тестового слоя.
И моя служба
package com.example.movies.domain.feature.software.service;
...
@Service("softwareService")
public class SoftwareServiceImpl
implements SoftwareService {
@Override
public SoftwareObject addSoftware(@Valid SoftwareObject software) {
// If gets into this method then software has to be valid (has been validated by ValidationAspect since is annotated with @Valid)
// ...
}
}
Я не понимаю, почему не вызывается аспект, поскольку bean-компонент mockedSoftwareService находится в пакете функций, а имя bean-компонента заканчивается на "Service", поэтому он удовлетворяет обоим условиям. Вы хоть представляете, что может происходить? заранее спасибо
РЕДАКТИРОВАТЬ
@Service("softwareService")
public class SoftwareServiceImpl
implements SoftwareService {
private static final Logger LOGGER = LoggerFactory.getLogger(SoftwareServiceImpl.class.getName());
private SoftwareDAO dao;
private MapperFacade mapper;
@Autowired
private SoftwareCriteriaSupport criteriaSupport;
@Autowired
private SoftwareDefaultValuesLoader defaultValuesLoader;
@Autowired
public SoftwareServiceImpl(SoftwareDAO dao) {
this.dao = dao;
}
@Autowired
@Qualifier("domainMapper")
public void setMapper(MapperFacade mapper) {
this.mapper = mapper;
}
// other methods
}
@RunWith(SpringJUnit4ClassRunner.class)
, поскольку Junit еще не привязан к контексту Spring :) - person Bond - Java Bond   schedule 09.06.2015