Reputation: 6145
In a Maven project A, there are a couple of Junit tests for some Java components.
My goal is to apply an aspect (using AspectJ) to the component classes and then execute the Junit tests. The aspect will do some counting of the component method calls.
I'm aware of the different methods to weave the code (compile, post-compile, load-time).
I'm also aware of the aspectj-maven-plugin
that i'd like to use.
The challenge I'm facing is that I don't want to touch any code of project A, like changing the pom.xml or adding the aspect. Also, i want to run the Junit tests of project A using Maven targets.
So my question is how to set up/configure another Maven project B that
Has anyone done anything similar and can point me in the right direction?
Upvotes: 0
Views: 293
Reputation: 67457
Note: This answer is preliminary. Its possible further development depends on the OP's feedback.
Several things come to my mind when reading your question:
If you want to count calls, why not just use something like Mockito with JUnit or switch to Spock with its built-in mocking capabilities completely? Why use aspects in order to count interactions? It is certainly possible, but what do you need that a mocking tool does not provide out of the box?
If the unit tests live in module A, why don't you want to touch that same module? Specifically, why don't you even want to touch the POM in order to ensure aspect weaving? That seems unnatural. You gave no good explanation for that. "I don't want to" does not count.
From a module B, you cannot just execute the unit tests of module A, unless of course you create a test JAR in A and depend on it in B. But even for that, you need to touch POM A in order to build the test JAR.
You have several more or less straightforward ways of solving your problem - always assuming that you don't just count your interactions with a mocking tool but actually do insist on using AspectJ:
Put the test aspect into A as a test class. Use load-time weaving (LTW) when running the tests, which can easily be configured in Surefire or Failsafe. That way, the application code stays unwoven and your aspect still is applied during testing.
If for some reason the test aspect is (really!) reusable and to be used in multiple modules, put it into module T and make A have a test-scoped dependendy on T. Do the same for all modules M1..Mn which need the same test aspect.
Of course you can create a test JAR along with the regular (unwoven) application JAR A and use both as dependencies in a module A_AspectTest where you do post-compile class file weaving with AspectJ Maven Plugin and execute the tests from the test JAR on the woven version of A. But not only does that seem unnecessarily complicated, it also would not solve the problem of the tests being executed in the original A project and then again in the woven A_AspectTest module. You would have to deactivate the Surefire execution in A in order to avoid that. But imagine a new developer joining your team, trying to understand your build... You get the picture.
My recommendation is to keep it simple and either use a mocking tool or one of options 1 or 2, in decreasing order of preference.
P.S.: The main criterion for me recommending LTW here is that the aspect is not a production aspect but a test aspect, i.e. the application code class files are not to be touched.
Upvotes: 0