Search code examples
spring-bootmavenaspectjspring-aopaspectj-maven-plugin

SpringBoot, AOP and tests: ok in Eclipse, but it fail in Maven


I beg for your help. For my project, https://github.com/hdsdi3g/prodlib, module jobkit, I can't pass 4 tests who pretend to validate calls via @Aspect.

Ok with Eclipse (the last version). Ko with Maven, the last version too.

How to reproduce:

   git clone https://github.com/hdsdi3g/prodlib
   git checkout issue51
   mvn install -DskipTests && mvn test -rf :jobkit
   # or just mvn test 

On class: https://github.com/hdsdi3g/prodlib/blob/issue51/jobkit/springboot-service/src/test/java/tv/hd3g/jobkit/mod/component/SupervisableAspectTest.java#L70

void testWithDefaultName() throws Exception {
        when(supervisableServiceSupplier.createAndStart("TestWithSupervisable.aSupervisableMethod"))
                .thenReturn(supervisable);

        testWithSupervisable.aSupervisableMethod(runnableWithException);
        verify(runnableWithException, times(1)).run(); //OK
        verify(supervisableServiceSupplier, times(1)).createAndStart("TestWithSupervisable.aSupervisableMethod"); // KO
        verify(supervisableServiceSupplier, times(1)).end(supervisable, Optional.empty());
}

Aspect class: https://github.com/hdsdi3g/prodlib/blob/issue51/jobkit/springboot-service/src/main/java/tv/hd3g/jobkit/mod/component/SupervisableAspect.java

    @Around("annotationWithSupervisable()")
    public Object manageSupervisable(final ProceedingJoinPoint joinPoint) throws Throwable {
        /* [...] */
        // THIS code run with Eclipse Test, but not with Maven... WHY ?
        [...]
        final var supervisable = supervisableServiceSupplier.createAndStart(jobName);
            final var result = joinPoint.proceed(joinPoint.getArgs());
            supervisableServiceSupplier.end(supervisable, Optional.empty());
            return result;
        [...]
    }

    @Pointcut("@annotation(tv.hd3g.jobkit.WithSupervisable)")
    public void annotationWithSupervisable() {
    }

Class to "aspect" as test: https://github.com/hdsdi3g/prodlib/blob/issue51/jobkit/springboot-service/src/test/java/tv/hd3g/jobkit/mod/component/TestWithSupervisable.java

@Component
public class TestWithSupervisable {

    @WithSupervisable
    void aSupervisableMethod(final RunnableWithException toTest) throws Exception {
        toTest.run();
    }

[...]

You can see the error https://github.com/hdsdi3g/prodlib/pull/52

[ERROR] Failures:
[ERROR]   SupervisableAspectTest.testWithDefaultName:76
Wanted but not invoked:
getSupervisableSupplier bean.createAndStart(
    "TestWithSupervisable.aSupervisableMethod"
);
-> at tv.hd3g.jobkit.engine.SupervisableServiceSupplier.createAndStart(SupervisableServiceSupplier.java:31)
Actually, there were zero interactions with this mock.

See the main pom: https://github.com/hdsdi3g/prodlib/blob/issue51/pom.xml and project pom https://github.com/hdsdi3g/prodlib/blob/issue51/jobkit/springboot-service/pom.xml

See the THIRD-PARTY.txt file to know the deps versions (all seem the lasts, too): https://github.com/hdsdi3g/prodlib/blob/issue51/jobkit/springboot-service/THIRD-PARTY.txt

Thanks for you help, or ideas!


All is working fine in Eclipse, but not in Maven test (surefire).

I want to know if my code/approach is wrong, or if my maven setup/pom is wrong!


Solution

  • Your test also fails in the IDE, if you run it together in the same session with SupervisableServiceSupplierTest in this order:

    1. SupervisableServiceSupplierTest
    2. SupervisableAspectTest

    Calling sss.end in the first test like this fixes the problem:

    @AfterEach
    void end() {
      verifyNoMoreInteractions(supervisableManager, supervisable, exception);
      sss.end(supervisable, Optional.empty());
    }
    

    This is a classical case of a test not cleaning up a fixture, bleeding over context to another test. It has nothing to do with Maven at all.

    P.S.: Your MCVE link was key for me to solve this case. You did yourself the greatest favour by providing it. Every newbie and many more experienced developers here can learn from this. Without a complete, reproducible example nobody would have had the slightest chance to debug this and provide a correct answer with the information given in the question as such, because like so often

    • someone trying to help needs to see for himself and play around with the code a bit,
    • the problem was in the code not shown in the question.