我正在使用 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());
}
}
所以这是测试,它应该在进入 addSoftware 方法之前抛出 ValidationException,因为它是一个无效的软件对象。
@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)
// ...
}
}
我不明白为什么不调用方面,因为 mockedSoftwareService bean 位于功能包中,并且 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
}