Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unresolved references when testing in another module with testImplementation project(:deepestModule)

I have a multi-module project setup. When testing, I found that I kept redefining some mocks in each module. So I was hoping to define my mock in the deepest module and reuse it in outer modules

What I did:

  1. I put the mock definition into test source set val mock = Mock(val id: String = "blah")
  2. Adjusted the outer module build file to say testImplementation project(:deepestModule)
  3. In outer module tests, I reference the mock like so assertThat(mock.id).isEqualTo("blah")

No compilation errors, but when I run my outer tests, the build fails with unresolved references to the mock.

Is there a trick to this?

like image 579
Vas Avatar asked Dec 17 '22 15:12

Vas


1 Answers

Test classes in one project are not exposed to other projects, not even the tests of those other projects. This is by design. Unit tests in a project are usually specific to that project and should not leak onto the classpath of anything else.

That being said, there is a legitimate use case for sharing mocks and other test resources. We generally call these test fixtures and it looks like this is exactly what you want.

If you are on Gradle 5.6 or later, there is direct support for that. You will have to apply the java-test-fixtures plugin and move your Kotlin test sources that define the mocks to src/testFixtures/kotlin. The actual unit tests should still reside in the test source set. The fixture can then be consumed in other projects with testImplementation(testFixtures(project(":deepestModule"))). You can read more about it in the Gradle user guide here.

If you are on an older version of Gradle, you will have to separate the test fixtures from the main source code. So in this case you will have to create a new sub-project with your test code. In this project, put the source in the main source set and don't use the test configurations. Write it like a normal library, even though it is only for tests. Then you can consume it the way you tried already with testImplementation(project(:deepestModule)).

By the way, is there a particular reason why you are using the Groovy DSL over the Kotlin DSL? Since you are building a Kotlin project anyway, the latter seems more appropriate.

like image 94
Bjørn Vester Avatar answered May 23 '23 19:05

Bjørn Vester