I've added an AOP (Aspect Oriented Programming) Aspect to my working project. It does work, but it won't be called when trying to Test it's functionality with an Integration Test.
The problem is, that the aspect is not called when the tests runs through. When using it normally it works fine.
I've tried to create a custom context which is supposed to be loaded for the integration tests, as I thought that the Aspect might not be loaded in the default context for these tests.
As this didn't work i also tried to manually proxy the bean of the aspect, but this didn't work neither.
Here's my integration test class:
@ComponentScan(basePackages = { "package.aspects" })
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ZirafyApp.class)
@ContextConfiguration(classes ={ IntegrationTestAOPConfiguration.class })
public class CellResourceIntTest {
private static CellTestHelper helper = new CellTestHelper();
@Autowired
private PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver;
@Autowired
private ExceptionTranslator exceptionTranslator;
@Autowired
private EntityManager em;
@Autowired
private BusinessFacade businessFacade;
@Autowired
private CellRepository cellRepository;
@Autowired
private AspectModule aspectModule;
private MockMvc restCellMockMvc;
private MappingJackson2HttpMessageConverter jacksonMessageConverter = new MappingJackson2HttpMessageConverter();
private Cell cell;
private Cell parentCell;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
final CellResource cellResource = new CellResource(cellRepository, businessFacade);
this.restCellMockMvc = MockMvcBuilders.standaloneSetup(cellResource)
.setCustomArgumentResolvers(pageableHandlerMethodArgumentResolver)
.setControllerAdvice(exceptionTranslator)
.setConversionService(createFormattingConversionService())
.setMessageConverters(jacksonMessageConverter).build();
}
@Test
@Transactional
public void update_cellDtoWithEmptyName_returnsHttpError422AndCellInDbIsNotUpdated() throws Exception {
AspectJProxyFactory factory = new AspectJProxyFactory(cellRepository);
factory.addAspect(aspectModule);
CellRepository cellRepository = factory.getProxy();
CellDto cellDtoToUpdate = new CellDto.Builder().id(2).name(null).x(-10).active(true).parent(1).build();
Cell parentCell = helper.createCell(1L);
Cell cellToUpdate = helper.createCell(2L);
cellRepository.saveAndFlush(parentCell);
cellRepository.saveAndFlush(cellToUpdate);
restCellMockMvc.perform(put("/api/cells/update")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(cellDtoToUpdate)))
.andExpect(status().is(200));
Cell updatedCell = cellRepository.findOne(2L);
assertEquals(cellToUpdate.getX(), updatedCell.getX());
}
Here the configuration file for the integration test:
@Configuration
@EnableJpaRepositories(basePackages = {"package.repository"})
@ComponentScan("ch.post.pf.aspects")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class IntegrationTestAOPConfiguration {
@Autowired
private ExceptionTranslator exceptionTranslator;
@Autowired
private EntityManager em;
@Autowired
private CellConverter cellConverter;
@Autowired
private CellTreeService cellTreeService;
@Autowired
private CellService cellService;
@Autowired
private CellRepository cellRepository;
@Autowired
private BusinessFacade businessFacade;
@Autowired
private AspectModule aspectModule;
@Bean
public CellConverter returnCellConverter() {
return cellConverter;
}
@Bean
public AspectModule returnAspectModule() {
return null;//Aspects.aspectOf(AspectModule.class);
}
@Bean
public PageableHandlerMethodArgumentResolver returnPageableArgumentResolver() {
return new PageableHandlerMethodArgumentResolver();
}
@Bean
public ExceptionTranslator returnExceptionTranslator() {
return exceptionTranslator;
}
@Bean
@Primary
public EntityManager returnEntityManager() { return em; }
@Bean
public BusinessFacade returnBusinessFacade() {
return businessFacade;
}
@Bean
public CellTreeService returnCellTreeService() {
return cellTreeService;
}
@Bean
public CellService returnCellService() {
return cellService;
}
}
And here my aspect-file:
@Aspect
@Component
public class AspectModule {
private BusinessFacade businessFacade;
@Autowired
AspectModule(BusinessFacade businessFacade){
this.businessFacade = businessFacade;
}
@Pointcut("execution(* ch.post.pf.web.rest.CellResource.update(..))")
private void update() {}
@Around("update() && args(cell)")
public Object checkIsValidCell(ProceedingJoinPoint pjp, CellDto cell) {
System.out.println("Aspect was run");
final String message = canUpdate(cell);
if (message.equals("cell_valid")) {
try {
return pjp.proceed(); // Calls the usual update() function, if the cell is valid
} catch (Throwable e) {
System.out.println("Something went wrong with the aspects");
System.out.println(e.toString());
return null;
}
} else {
deleteIfCellWasEmpty(cell);
return ResponseUtil.unprocessableEntity(message);
}
}
}
The aspect should keep working as it does right now but it should also work in the integration tests, at the moment it isn't called at all inside those.