Hot questions for Using Mockito in aspectj

Hot questions for Using Mockito in aspectj

Question:

I am trying to write Junit tests for Custom Aspect. Here is the Aspect Class Snippet:

@Aspect
@Component
public class SampleAspect {

    private static Logger log = LoggerFactory.getLogger(SampleAspect.class);

    @Around("execution(* org.springframework.data.mongodb.core.MongoOperations.*(..)) || execution(* org.springframework.web.client.RestOperations.*(..))")
    public Object intercept(final ProceedingJoinPoint point) throws Throwable {
        logger.info("invoked Cutom aspect");
         return point.proceed();

    }

}

So the above aspect intercepts whenever jointpoint matches the pointcut. Its working fine.

But my question is how to unit test that class. I have the following Junit Test:

@Test(expected = MongoTimeoutException.class)
    public void TestWithMongoTemplate() {
        //MongoDocument class
        TestDocument test = new TestDocument();

        ApplicationContext ctx = new AnnotationConfigApplicationContext(TestMongoConfigurationMain.class);
        MongoTemplate mongoTemplate = ctx.getBean(MongoTemplate.class);

        //this call is being intercepted by SampleAspect
        mongoTemplate.save(test);

    }

So my mongoTemplate.save(test) in Junit is being intercepted by SampleAspect as it matches pointcut. But how should I make sure in junits(probably by asserting) that my SampleAspect is intercepting when that joint point is invoked?

I cannot assert on return value from intercept() as it does nothing special other than executing joint point. So my Junit cannot find any difference whether its being executed by aspect or a regular execution based on return values.

Any code snippets examples on aspect testing would be great if provided.Thanks


Answer:

I think what you are trying to test is aspect weaving and pointcut matching. Please note that that would be an integration rather than a unit test. If you really want to unit test your aspect logic and because you have tagged the question by "mockito" anyway, I suggest you do just that: Write a unit test and mock the aspect's joinpoint and maybe its other parameters, if any. Here is a slightly more complex example with some intra-aspect logic:

Java class to be targeted by aspect:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        new Application().doSomething(11);
        new Application().doSomething(-22);
        new Application().doSomething(333);
    }

    public void doSomething(int number) {
        System.out.println("Doing something with number " + number);
    }
}

Aspect under test:

package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class SampleAspect {
    @Around("execution(* doSomething(int)) && args(number)")
    public Object intercept(final ProceedingJoinPoint thisJoinPoint, int number) throws Throwable {
        System.out.println(thisJoinPoint + " -> " + number);
        if (number < 0)
            return thisJoinPoint.proceed(new Object[] { -number });
        if (number > 99)
            throw new RuntimeException("oops");
        return thisJoinPoint.proceed();
    }
}

Console log when running Application.main(..):

As you can see, the aspect passes on 11, negates -22 and throws an exception for 333:

execution(void de.scrum_master.app.Application.doSomething(int)) -> 11
Doing something with number 11
execution(void de.scrum_master.app.Application.doSomething(int)) -> -22
Doing something with number 22
execution(void de.scrum_master.app.Application.doSomething(int)) -> 333
Exception in thread "main" java.lang.RuntimeException: oops
    at de.scrum_master.aspect.SampleAspect.intercept(SampleAspect.aj:15)
    at de.scrum_master.app.Application.doSomething(Application.java:10)
    at de.scrum_master.app.Application.main(Application.java:7)

Unit test for aspect:

Now we really want to verify that the aspect does what it should and cover all execution paths:

package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import static org.mockito.Mockito.*;

public class SampleAspectTest {
    @Rule
    public MockitoRule mockitoRule = MockitoJUnit.rule();

    @Mock
    private ProceedingJoinPoint proceedingJoinPoint;

    private SampleAspect sampleAspect = new SampleAspect();

    @Test
    public void testPositiveSmallNumber() throws Throwable {
        sampleAspect.intercept(proceedingJoinPoint, 11);
        // 'proceed()' is called exactly once
        verify(proceedingJoinPoint, times(1)).proceed();
        // 'proceed(Object[])' is never called
        verify(proceedingJoinPoint, never()).proceed(null);
    }

    @Test
    public void testNegativeNumber() throws Throwable {
        sampleAspect.intercept(proceedingJoinPoint, -22);
        // 'proceed()' is never called
        verify(proceedingJoinPoint, never()).proceed();
        // 'proceed(Object[])' is called exactly once
        verify(proceedingJoinPoint, times(1)).proceed(new Object[] { 22 });
    }

    @Test(expected = RuntimeException.class)
    public void testPositiveLargeNumber() throws Throwable {
        sampleAspect.intercept(proceedingJoinPoint, 333);
    }
}

Now run this simple JUnit + Mockito test in order to test the aspect logic in isolation, not the wiring/weaving logic. For the latter you would need another type of test.

P.S.: Only for you I used JUnit and Mockito. Usually I just use Spock and its built-in mocking capabilities. ;-)

Question:

I am trying to write Integratation tests for Custom Aspect. Here is the Aspect Class Snippet.

@Aspect
@Component
public class SampleAspect {

    private static Logger log = LoggerFactory.getLogger(SampleAspect.class);

   private int count;

   public int getCount(){
      return count;
   }

    public void setCount(){
      this.count= count;
    }


    @Around("execution(* org.springframework.data.mongodb.core.MongoOperations.*(..)) || execution(* org.springframework.web.client.RestOperations.*(..))")
    public Object intercept(final ProceedingJoinPoint point) throws Throwable {
        logger.info("invoked Cutom aspect");
         setCount(1);
         return point.proceed();

    }

}

So the above aspect intercepts whenever jointpoint matches the pointcut. Its working fine. But my question is how to perform Integration test.

What I have done is I created the attribute "count" in Aspect for tracking and asserted it in my Junit. I am not sure if this is good or is there a better way of doing integration testing on aspects.

Here is the snippet of Junit what I have done. I presented in bad way but I hope its undestandable of what I have done for Integration testing.

@Test
public void testSamepleAspect(){
   sampleAspect.intercept(mockJointPoint);
   Assert.assertEquals(simpleAspect.getCount(),1);
}

Answer:

Let us use the same sample code as in my answer to the related AspectJ unit testing question:

Java class to be targeted by aspect:

package de.scrum_master.app;

public class Application {
    public void doSomething(int number) {
        System.out.println("Doing something with number " + number);
    }
}

Aspect under test:

package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class SampleAspect {
    @Around("execution(* doSomething(int)) && args(number)")
    public Object intercept(final ProceedingJoinPoint thisJoinPoint, int number) throws Throwable {
        System.out.println(thisJoinPoint + " -> " + number);
        if (number < 0)
            return thisJoinPoint.proceed(new Object[] { -number });
        if (number > 99)
            throw new RuntimeException("oops");
        return thisJoinPoint.proceed();
    }
}

You have several options, depending on what exactly you want to test:

  1. You can run the AspectJ compiler and verify its console output (with weaving info enabled) in order to make sure that the expected joinpoints are actually woven and others are not. But this would rather be a test for your AspectJ configuration and the build process as such than a real integration test.
  2. Similarly, you can create a new weaving classloader, load the aspect and then a few classes (load-time weaving, LTW) in order to dynamically check what gets woven and what does not. In this case you are rather testing if your pointcuts are correct than the integrated application consisting of core + aspect code.
  3. Last, but not least, you can perform a normal integration test, assuming how the application should behave after core + aspect code have been woven correctly. How to do this depends on you concrete situation, specifically on what kind of side effect your aspect adds to the core code.

Subsequently I will describe option no. 3. Looking at the sample code above, we see the following side effects:

  • For small positive numbers the aspect passes through the original parameter value to the intercepted method, the only side effect being additional log output.
  • For negative numbers the aspect passes through the negated parameter value (e.g. turning -22 into 22) to the intercepted method, which is nicely testable.
  • For larger positive numbers the aspect throws an exception, effectively stopping the original method from being executed at all.

Integration test for aspect:

package de.scrum_master.aspect;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.matches;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import java.io.PrintStream;

import org.junit.*;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import de.scrum_master.app.Application;

public class SampleAspectIT {
    @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

    private Application application = new Application();

    private PrintStream originalSystemOut;
    @Mock private PrintStream fakeSystemOut;

    @Before
    public void setUp() throws Exception {
        originalSystemOut = System.out;
        System.setOut(fakeSystemOut);
    }

    @After
    public void tearDown() throws Exception {
        System.setOut(originalSystemOut);
    }

    @Test
    public void testPositiveSmallNumber() throws Throwable {
        application.doSomething(11);
        verify(System.out, times(1)).println(matches("execution.*doSomething.* 11"));
        verify(System.out, times(1)).println(matches("Doing something with number 11"));
    }

    @Test
    public void testNegativeNumber() throws Throwable {
        application.doSomething(-22);
        verify(System.out, times(1)).println(matches("execution.*doSomething.* -22"));
        verify(System.out, times(1)).println(matches("Doing something with number 22"));
    }

    @Test(expected = RuntimeException.class)
    public void testPositiveLargeNumber() throws Throwable {
        try {
            application.doSomething(333);
        }
        catch (Exception e) {
            verify(System.out, times(1)).println(matches("execution.*doSomething.* 333"));
            verify(System.out, times(0)).println(matches("Doing something with number"));
            assertEquals("oops", e.getMessage());
            throw e;
        }
    }
}

Et voilĂ , we are testing exactly the three types of side effects our sample aspect has by inspecting log output to a mock instance of System.out and by making sure that the expected exception is thrown for larger positive numbers.

Question:

I have a Spring MVC application where I use an Aspect to catch exceptions in all controller methods

@Component
@Aspect
public class ControllerExceptionAspect {

    private Logger logger;

    public ControllerExceptionAspect() {
       logger = Logger.getLogger(ControllerExceptionAspect.class);
    }

    public ControllerExceptionAspect(Logger logger) {
       this.logger = logger;
    }

    // Catching all exceptions from all methods in all controllers classes

    @AfterThrowing(pointcut = "execution(* com.my.package..controller..*(..))", throwing = "exception")
    public void afterThrowingAdvice(Exception exception) {
       logger.error("CONTROLLER ASPECT: EXCEPTION IN METHOD -> " +    
       exception.getClass());
    }
}

Aspect works fine but unfortunatelly I can not test it. I tried many times but can not get how to catch whether an Aspect method was called after I simulate exception in Controller

@SuppressWarnings("ALL")
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextHierarchy({
        @ContextConfiguration(classes = RootConfig.class),
        @ContextConfiguration(classes = WebConfig.class)
})
public class ControllerExceptionAspectTest {

    @Autowired
    ApplicationContext applicationContext;

    @Test
    public void testControllerExceptionAspectGetsExecutedWhenExceptionOccures(){
        HomeController homeController = (HomeController)applicationContext.getAutowireCapableBeanFactory().getBean("homeController");
        try{homeController.callMethod("00000");}
        catch (Exception e){}
        ControllerExceptionAspect controllerExceptionAspect = (ControllerExceptionAspect)applicationContext.getAutowireCapableBeanFactory().getBean("controllerExceptionAspect");
        // HOW TO CATCH THAT ASPECT METHOD WAS CALLED???
    }
}

Answer:

I think that what you're trying to achieve is testing the configuration which you created (aspects pointcut), rather than aspect itself which could be unit tested. What I'm afraid is that there's no simple way of achieving that.

You could follow some internet advices on catching logs or other ideas. Honestly I'd test the expected behavior of the Aspect only if you really need to test that it was invoked. If it's loging I wouldn't do it. If it's setting something to the db (or other side effect) I'd verify if the value is in the db. That's the sloppy ground of integration testing.

If you really, really must test the aspect the way you want, you can write something similar the given code. But remember that normal (not-test) runtime spring configuration would require a dummy implementation of Verifier interface existing in the Spring context.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Config.class)
public class AspectTesting {

    @Autowired
    ServiceWithAspect service;

    @Autowired
    Verifier verifyingAspect;

    @Test
    public void test() {
        // given
        boolean condition = false;

        // when
        try {
            service.doit();
        } catch (Exception swallow) {}

        // then
        try {
            condition = ((VerifyingAspect) ((Advised) verifyingAspect).getTargetSource().getTarget()).wasExecuted();
        } catch (Exception swallow) {}

        // then
        Assert.assertTrue(condition);
    }
}

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("aspects")
class Config {
}

@Component
class VerifyingAspect implements Verifier {

    private boolean executed = false;

    public boolean wasExecuted() {
        return executed;
    }

    @Override
    public void invoked() {
        executed = true;
    }
}

@Service
class ServiceWithAspect {
    public void doit() {
        throw new RuntimeException();
    }
}

@Component
@Aspect
class TestedAspect {

    @Autowired
    Verifier verifier;

    @AfterThrowing(pointcut = "execution(* *(..))", throwing = "exception")
    public void afterThrowingAdvice(Exception exception) {
        // your aspect logic here
        verifier.invoked();
    }
}

interface Verifier {
    void invoked();
}

Question:

Background

A project uses Aspects for logging. The particulars:

  • Java 11
  • AspectJ 1.9.4 (runtime, tools, compiler, post-compile-weaving plugin)
  • Mockito Core 2.25.1

The build.gradle file resembles:

apply plugin: "io.freefair.aspectj.post-compile-weaving"

dependencies {
    compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
    compileOnly group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.12.1'
    compileOnly group: 'org.osgi', name: 'org.osgi.framework', version: '1.9.0'
    compileOnly group: 'org.mockito', name: 'mockito-core', version: '2.25.1'

    inpath project(":company.project.main")
}
Problem

When the application is compiled, AspectJ cannot find MockMethodDispatcher, and reports an error:

.../mockito-core-2.25.1.jar [error] can't determine superclass of missing type org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher
when weaving type org.mockito.internal.creation.bytebuddy.MockMethodAdvice
when weaving classes 
when weaving 
when batch building BuildConfig[null] #Files=0 AopXmls=#0
 [Xlint:cantFindType]
(no source information available)
        [Xlint:cantFindType]
.../org.mockito/mockito-core/2.25.1/e8fa2864b65c0b6fbb20daa436a94853bcd17e5e/mockito-core-2.25.1.jar [warning] can't find type org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher whilst determining signatures of call or execution join point for java.util.concurrent.Callable org.mockito.internal.creation.bytebuddy.MockMethodAdvice.handle(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]), this may cause a pointcut to fail to match at this join point 
when weaving type org.mockito.internal.creation.bytebuddy.MockMethodAdvice
when weaving classes 
when weaving 
when batch building BuildConfig[null] #Files=0 AopXmls=#0
 [Xlint:cantFindTypeAffectingJPMatch]

I suspect this is because the file is stored as a .raw file rather than a .class file (as per issue 845):

1778 Mon Jul 08 13:47:02 PDT 2019 org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.raw
Question

How would you update the Gradle file to instruct the post-compile-weaving plugin to ignore weaving (or scanning) Mockito classes altogether?

Notes

From the command-line, weaving appears to work:

java -cp aspectjtools-1.9.4.jar:aspectjrt-1.9.4.jar org.aspectj.tools.ajc.Main \
-inpath application.jar \
-aspectpath ../aspects/build/classes/java/main \
-Xlint:warning \
-verbose \
-showWeaveInfo \
-log aop.log \
-outjar woven.jar

Though the output classes in woven.jar should be injected into application.jar.

Addendum

Note:

  • Working around the issue by adorning the @Aspect-annotated class with a !within @Pointcut annotation is not viable. Would strongly prefer to pass an argument to ajc via the plugin.
  • Downgrading cantFindType from an error to a warning would be a satisfactory answer, but not ideal (stuck on syntax), as I'd like other cantFindType errors to remain as errors.
Related
  • Gradle and AspectJ - avoid weaving my own packages during compile time
  • How to set "-aspectpath" for the FreeFair AspectJ Gradle Plugin?
  • AspectJ + Gradle configuration
Attempts

When calling compileJava as follows:

compileJava {
    ajc {
        enabled = true
        classpath = configurations.aspectj
        options {
            aspectpath = configurations.aspect
            compilerArgs = [""]
        }
    }
}

Gradle reports the following error:

Cannot set the value of read-only property 'classpath' for object of type io.freefair.gradle.plugins.aspectj.AjcAction.

Using:

compileJava {
  ajc {
    options {
      compilerArgs = [""]
    }
  }
}

Gradle reports:

Could not find method options() for arguments [...] on object of type io.freefair.gradle.plugins.aspectj.AjcAction.

The source code on master seems to expose different names for its "configurable things":

task.getInputs().property("ajcArgs", this.getOptions().getCompilerArgs())

Answer:

The declared dependency is transitive:

inpath project(":company.project.main")

This will pass the complete runtime classpath of :company.project.main (the classes produced by said project and all its dependencies) into the -inpath of ajc. (See the build/tmp/compileJava/ajc.options file to confirm.)

To avoid weaving advices into external classes, declare a non-transitive dependency as follows:

inpath(project(":company.project.main")) { 
    transitive = false
}

Depending on your exact requirements and your project structure, it might be a better approach to apply the io.freefair.aspectj.post-compile-weaving plugin directly to the :company.project.main project.

Question:

I have the following test class and I'm using Mockito's spy. By running my unit test using Eclipse (right click->Run as unit test) all tests pass which means that eclipse build process using m2e and AJDT works fine.

@RunWith(MockitoJUnitRunner.class)
public class SampleTest {

@Mock
private AnotherClazz mockedClazz;

@Spy
@InjectMocks
private SampleImpl sampleService = new SampleImpl() {

    @Override
    public void someMethod() {
       ...
    }
};


@Test
public void someTest() throws Exception {
    sampleService.methodUnderTest();
}

However when I use maven to run the tests I get the following exception.

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.183 sec <<<     FAILURE!
    org.sample.SampleTest  Time elapsed: 0.182 sec  <<< ERROR!
    org.mockito.exceptions.base.MockitoException: Problems initiating spied field     sampleService
    at     org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.withBefores(JUnit45AndHigherRunnerImpl.java:27)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:254)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class org.sample.SamplelTest$1
Mockito can only mock visible & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
    ... 25 more
Caused by: org.mockito.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
    at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:238)
    at org.mockito.cglib.proxy.Enhancer.createHelper(Enhancer.java:378)
    at org.mockito.cglib.proxy.Enhancer.createClass(Enhancer.java:318)
    at org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:123)
    at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57)
    at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49)
    at org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)
    at org.mockito.Mockito.mock(Mockito.java:1285)
    at org.mockito.internal.configuration.injection.SpyOnInjectedFieldsHandler.processInjection(SpyOnInjectedFieldsHandler.java:43)
    at org.mockito.internal.configuration.injection.MockInjectionStrategy.process(MockInjectionStrategy.java:68)
    at org.mockito.internal.configuration.injection.MockInjectionStrategy.relayProcessToNextStrategy(MockInjectionStrategy.java:89)
    at org.mockito.internal.configuration.injection.MockInjectionStrategy.process(MockInjectionStrategy.java:71)
    at org.mockito.internal.configuration.injection.MockInjection$OngoingMockInjection.apply(MockInjection.java:93)
    at org.mockito.internal.configuration.DefaultInjectionEngine.injectMocksOnFields(DefaultInjectionEngine.java:20)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.injectMocks(InjectingAnnotationEngine.java:100)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.processInjectMocks(InjectingAnnotationEngine.java:62)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:56)
    at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108)
    ... 25 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.mockito.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:385)
    at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:220)
    ... 44 more
Caused by: java.lang.VerifyError: Cannot inherit from final class
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    ... 50 more

What is here the difference between the AJC compiler used in Eclipse with AJDT and my AspectJ maven plugin configuration? Which configuration or phase am I missing here?

Here is my pom.xml:

<dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.6.11</version>
</dependency>
<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.4</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
            <executions>
                <execution>
                    <phase>process-sources</phase>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Update: I haven't found a solution yet but I know why is this happening. The problem actually lies here on overriding the someMethod(). Removing the method override or commenting out the aspectj maven plugin solves the problem as a workaround. I cannot let AspectJ out of my project so I have to mock the someMethod() as well without overriding it (e.g. using Mockito itself). It looks like a bug for me but I'm not quite sure does it come from AspectJ or Mockito.


Answer:

What is here the difference between the AJC compiler used in Eclipse with AJDT and my AspectJ maven plugin configuration?

Well, you use a very old AspectJ compiler and runtime from 2011 in Maven, but your AJDT probably uses a much more recent version. BTW, does your code really have to be compliant to Java 6? Anyway, that should not be a problem, but I recommend to use the current AspectJ Maven Plugin 1.7 and also the latest AspectJ version. You can still compile 1.6-compatible code with it. When I tried to recreate your situation with the old AspectJ version, the code would not even compile, but you have not provided a real SSCCE, so I have no idea about your JDK version, Mockito version, JUnit version etc.

Try this Maven configuration in your POM:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.6</java.version>
    <aspectj.version>1.8.6</aspectj.version>
</properties>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.3</version>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <!-- IMPORTANT -->
                <useIncrementalCompilation>false</useIncrementalCompilation>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <configuration>
                <showWeaveInfo>true</showWeaveInfo>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <Xlint>ignore</Xlint>
                <complianceLevel>${java.version}</complianceLevel>
                <encoding>UTF-8</encoding>
                <verbose>true</verbose>
            </configuration>
            <executions>
                <execution>
                    <!-- IMPORTANT -->
                    <phase>process-sources</phase>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>1.9.5</version>
        <scope>test</scope>
    </dependency>
</dependencies>

This works for me. BTW, please note the <complianceLevel> in addition to <source> and <target>.