Maven test dependency not being found - maven

I'm declaring a test dependency on powermock with easymock bundled in.
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>1.4.12</version>
<type>pom</type>
<scope>test</scope>
</dependency>
When I run mvn test, the test src claims to be able to find org.powermock but not org.easymock, despite it being included in the above dependency.
I wondered whether it was a problem due to transitivity of the test scope, so i tried compile scope also (as the documentation http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html mentions that the compile dependencies are available at test time) without any luck.
I've also tried using a bundled jar instead of pom, to no avail. I realise i could declare the dependencies separately (ie separate dependencies for powermock and easymock) but for my purposes i'm restricted to having just the one dependency including all necessary test libs.

Tracing this back to the powermock parent pom I see that the easymock dependency is marked "provided."
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.1</version>
<scope>provided</scope>
</dependency>
Looks like powermock is expecting its clients (you in this case) to supply the easymock jars.

According to the powermock-easymock-release-full POM, it does not depend on easymock (ie easymock does not appear in the powermock-easymock-release-full dependencies). So you'll have to add another dependency to easymock, dependending on the test engine you're using (JUnit or TestNG): http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.powermock%22%20AND%20%22easymock%22

Related

How to include kotlin.test properly via Maven?

Our team is making first steps into Kotlin and I'm about to to migrate a test. I tried a first example from mockk (https://github.com/mockk/mockk/blob/master/mockk/common/src/test/kotlin/io/mockk/it/InjectMocksTest.kt). For some reason it seems I'm not able to use kotlin.test although I have added it via maven. Do I have to include any other modules? Or do I have to change something else?
(the mockk example uses Gradle so it doesn't help me).
This is what I'd like to use in my Kotlin test file but it which can't be found (at least not the packages I need):
(Restarting Intellij doesn't help, neither running mvn seperately)
This is my maven dependancy (Intellij shows now error):
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version> <!-- kotlin.version == 1.7.0 -->
<scope>test</scope>
</dependency>
The solution was (see hotkey's answer) to add the following maven dependency:
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit5</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
You need to add a dependency on one of kotlin-test-junit (for JUnit 4), kotlin-test-junit5 (for JUnit Jupiter), or kotlin-test-testng (for TestNG), depending on what test framework you are using.
The artifact kotlin-test contains only the common code, asserters and other stuff that can be reused across the frameworks.
The kotlin.test annotations like #Test or #BeforeTest are shipped in the test-framework-specific artifacts as typealiases to the actual annotations types of the test frameworks.

Two Maven Dependencies with different scope

If I have the following two dependencies in the same pom.xml file:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
And I'd like to remove the redundancy. So should I delete the one with scope as runtime because it's included in the other dependency?
Also I'd be happy to understand why one would specify a dependency with scope of runtime.
From Introduction to the Dependency Mechanism - Dependency Scope:
compile
This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.
(...)
runtime
This scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath.
So if you have a compile dependency, runtime is already included and therefore superfluous.
As an example for when to use runtime, take the SLF4J logging API: you compile your sources against slf4j-api.jar (compile dependency), but not the actual implementation, which is distributed separately (and there are several to choose from). However, when packaging your application or running unit tests, Maven should still include an implementation jar, e.g. slf4j-simple.jar (runtime dependency), because otherwise nothing will be logged.

Using Spring autowired bean from other project in JUnit

I'm writing unit tests for my app consisting of several projects. I have project A for which I'm writing tests, and project B where I want to store some needed beans to be autowired in A test classes.
Prject A also needs B in the compilation scope.
If using dependency like that:
...
A/pom.xml
...
<dependency>
<artifactId>B</artifactId>
<scope>compile</scope>
<dependency>
spring is unable to autowire beans of B project. It's strange, because according to the Maven docs, compile scope also makes project content available at the stage phase.
In case I use the save dependency but with test scope, unit tests work, but app itself faild (pretty predictable).
In case when I use both dependencies, like:
...
A/pom.xml
...
<dependency>
<artifactId>B</artifactId>
<scope>compile</scope>
<dependency>
<dependency>
<artifactId>B</artifactId>
<scope>compile</scope>
<type>test-jar</type>
<scope>test</scope>
<dependency>
mvn clean install fails since it's unable to resolve dependencies.
So what can I do? Is there any best practise of using other project beans in unit tests in Spring?
The default maven scope (compile) should do it. Should give you access to the classes at compile/test time.
You should look at:
what packaging do you use for each project (jar/war)
how are you autowiring beans from B to A, does the autowiring works at runtime,
maybe there is a difference on how you create the Spring context at test time VS runtime
could be that Spring auto-scan mechanism doesn't scan the B project packages (at least in tests)
We usually do it like :
<dependency>
<artifactId>B</artifactId>
<groupId>groupID</groupId>
<version>version number</version>
<scope>compile</scope>
<type>jar or war</type>
</dependency>

Why order of Maven dependencies matter?

I thought that the order of Maven dependencies doesn't matter before and regard this as a pro of it. And this is my old pom.xml's dependencies:
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
It works well, and today I wanna move spring dependency to the bottom so that those jersey related can be together. However then I can no longer make it working, my Jetty complains:
[ERROR] Failed to execute goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run (default-cli) on project mtest: Execution default-cli of goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run failed: A required class was missing while executing org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run: org/apache/commons/logging/LogFactory
That is really confusing, so do I have to concern about dependencies order? How do I know the correct order?
The order of dependencies does matter because of how Maven resolves transitive dependencies, starting with version 2.0.9. Excerpt from the documentation:
(...) this determines what version of a dependency will be used when multiple versions of an artifact are encountered. (...) You can always guarantee a version by declaring it explicitly in your project's POM. (...) since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.
To expand upon the other answer (which states that the declaration order affects Maven's dependency mediation for transitive dependencies), there are a few tools you can use:
mvn dependency:tree [-Dscope=[runtime|test]] will show you what dependencies will be available for the selected scope. See here for details
mvn dependency:build-classpath gives you order in which dependencies are available on your classpath (if two or more classpath entries have the same class, the earlier one wins). See here for details
I don't know much about your situation, but it's often the case that you wind up with the wrong version of 1 or more jars at compile/runtime. Declaring your own version of the library in question or locking down the version with <dependencyManagement> are options here.
Now to answer your other question - how do you know what the right order is when declaring dependencies?
My suggestion - the right declaration order is the one that gets you the versions of the dependencies you want, in the order you want them in. Use the tools above to check your dependencies, and tweak the declared order if necessary.
Note that most jars contain disjointedly-named classes, so the exact order in which jars appear on your classpath is usually not that important. The only exception I've noticed is some jars in SLF4J which intentionally shadow classes from the other logger libraries it's intended to replace.

Maven same dependency on different scopes

I have a maven (3) project with multiple submodules. One on of them, I want it to explicitly depend on a dependency, without depending on its transitive dependencies. To do this, I'm using the folloing:
<dependency>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
This works as itended. During runtime, the transitive dependencies of "foo" will already be in the classpath, so everything goes well.
However, I need "foo"'s transitive dependencies for test. I tried to also declare a dependency of "foo" with scope test, but it seems that it conflicts with the one that excludes everything. It either works as expected in tests but fails in runtime, or vice-versa.
Do you known if something like this is possible with maven?
Of course it's possible, you need to declare 2 different maven profiles holding your dependencies.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
Different dependencies for different build profiles in maven
You should check out Maven's <scope>import</scope> dependencies. Create a <profile/> for testing and define a dependency to a pom which contains these test dependencies you're interested in. (This might require some re-working of your pom.xml-s, but would be a good approach).
Check here for more details.

Resources