Dagger 2: Separate Module for testing declared in src/test/java - maven

I have a Maven project and defined a module + component in src/main/java, which Dagger 2 is handling as expected.
Now I want to mock some dependencies for my unit tests. However the dagger-compiler seems to ignore components inside src/test/java.
Is there a way of telling Dagger 2 to also look inside my test source set?
(Not an Android project)

Ok found my mistake. For others having the same problem: This question gave me the correct hint.
Components declared in src/test/java are generated to target/generated-test-sources/. This is an annotation processing default, not Dagger's fault. I just didn't have the idea to look for directories other than target/generated-sources...

Related

maven test dependencies of dependencies

I have a large project and i want to add an integration tests module which will depend on every thing and validate interaction between modules.
The issue is that during the test I'm missing the dependency classes
module A uses module B
I have a test on module A testing something that uses module B, and I'm getting an error stating it can't find classes in module B.
I tried surefire but there is no difference.
I know I can and I should mock the classes in B which aren't part of the test but I want a full test that will test everything.
As official Maven documentation declares test scope is not transitive. You need to declare required dependencies explicitly in the pom file(s).
You cannot change this behaviour, but there is usually no need to change this behaviour.
If you want to write a library that is used for testing, then this library should have compile dependencies, but when you use it, declare it with scope test.

Equivalent of api for test dependency in gradle?

I'm having multi module gradle project. In one of my modules I'm having api dependency:
api('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
I want to change it to dependency that will be visible in tests, across all modules. There is a testImplementation dependency but there is no testApi.
I cannot have this dependency on production classpath anymore since I want to use real mongo instance instead of embedded one. On the other hand I have tests in different modules that depend on data access - in that case I want to run those test with embedded mongo on test classpath.
How I can make this dependency visible in all modules tests?
The question (appears to me) is sharing the test code across modules in a multi-module project
Short answer - No - there is direct test dependency share across modules.
To share test code between modules internally via build settings
Official gradle route https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures
Simple hack
testImplementation files(project(':core-module').sourceSets.test.output.classesDirs)
add the above line either individually where you need or in root with subprojects() with appropriate condition
*there are other possible routes as well *
ex: via configuration
child.testImplementation extends parent.testImplementation (or runtime)
testCompileClassPath includes api dependencies so you are all good here, de.flapdoodle.embed.mongo will be visible in your tests.

Why isn't JUnit's assertTrue being resolved?

I have a project that follows the standard Maven structure:
project
src
main
java
test
java
In some classes, assertTrue is able to be resolved, and in others it cannot be resolved.
I took the static import from the class (in the src/java/test directory) that is resolving and pasted it into the class that can't resolve assertTrue (in the src/java/main directory) and that didn't resolve it.
So using import static org.junit.Assert.assertTrue; doesn't work.
Using Assert.assertTrue doesn't work either.
Edit:
One thing that I didn't make clear in the initial post is that this isn't a standard Java project with unit tests. The project is the integration test framework for another Java program. So all the code within this project exists to test the functionality of another program using the external REST API. Hence why I had a Junit assertion outside the test folder. Granted there may still be an opportunity to clean that up.
So the issue was in my build.gradle file that I had specified the junit dependency as a testCompile dependency. Meaning that it would only be apply to classes within the src/test directory. So to resolve my issue, I changed the build.gradle to use compile('junit:junit:4.12').
I could have also moved the file that wasn't resolving into the src/test directory, but the file didn't logically belong there.

Spring Resource Loading

Can anyone explain how Spring decides where to look for resources when one uses the ResourceLoader.getResource(...) method?
I am having a problem with a multi-module maven application built using Spring Boot whereby in my integration tests my code is able to find resources using resourceLoader.getResource("templates/") or even resourceLoader.getResource("classpath:templates/"). So far so good...
However, when the module is eventually packaged into the executable JAR and run with embedded Tomcat the resources can no longer be resolved. I also tried resourceLoader.getResource("classpath*:templates/") with no success.
What I find concerning is that when I add a logging statement to output the URL being used in the search i get a path to one of the other modules in the project (not the one that actually contains the resource in question). E.g: jar:file:/Users/david/exmaple/target/spring-boot-0.0.1-SNAPSHOT.jar!/lib/module1-0.0.1-SNAPSHOT.jar!/templates/ whereas I believe the resource is in jar:file:/Users/david/exmaple/target/spring-boot-0.0.1-SNAPSHOT.jar!/lib/module2-0.0.1-SNAPSHOT.jar!/templates/
The resource loader was obtained from an Autowired constructor param.
Thanks in advance for any hints.
Edit
Just in case it isn't clear or is of importance, my integration tests for the module in question aren't aware of the other module. I have module1, module2 and a spring-boot module which has dependencies on module1 & module2. Essentially, when I run the integration tests for module 2 the classpath isn't aware of module1 - so I suspect that this has something to do with why it works in the tests.
When you use classpath: or classpath*: prefix, internally, this essentially happens via a ClassLoader.getResources(…​) call in spring.
The wildcard classpath relies on the getResources() method of the underlying classloader. As most application servers nowadays supply their own classloader implementation, the behavior might differ especially when dealing with jar files. A simple test to check if classpath* works is to use the classloader to load a file from within a jar on the classpath: getClass().getClassLoader().getResources("<someFileInsideTheJar>"). Try this test with files that have the same name but are placed inside two different locations. In case an inappropriate result is returned, check the application server documentation for settings that might affect the classloader behavior.
Do not use classpath: form as you have multiple classloader locations of templates/ .
Refer to: resources-classpath-wildcards

Multiple reusable modules in maven

I have a couple of java modules set up in IDEA and I am wanting to mavenize them. These java modules use classes from one another.
I was not quite sure how I should take up this and I decide to add modules on a maven project using IDEA. Hence first I created a maven project, let's name it pm1 which has a class let's name it TempClass1. Now this class can be used in other maven project. Hence I added another maven module - pm11 and tried to use TempClass1 with in pm11. It worked and I notices that IDEA had added module dependency of pm1 in pm11. So whole structure looks as -
But now when I do mvn test from pm11 then it fails with error message package package1 does not exist and it looks to me that it is because package1 is in a different maven project. And I am not sure how I could use classes which reside in a different maven project. I hope I am clear in my question.
You can use classes of other maven projects, as long as there's a proper maven dependency defined in pom.xml. Ensure that the dependency is defined and its' scope is either undefined or relevant (You may have problems if the scope is provided for example).

Resources