iddqd
iddqd

Reputation: 1305

Overriding src clases with test classes for java unit testing

I am trying to understand the JUnit way of imports classes at test time.
I noticed that creating a mock class with the same name of a src class, and the same package, will cause a test to import that one instead of the real src class.
For example :

src/main/java/MyObject.java
src/main/java/ObjectPrinter.java

src/test/java/MyObject.java
src/test/java/ObjectPrinterTest.java

Where both the main/java/MyObject.java and the test/java/MyObject.java declares the same package (both files starts with the same package XXX decleration). The ObjectPrinter.java (which is called by ObjectPrinterTest.java at test time) will have an import XXX.MyObject decleration.

How is it that in test time the import XXX.MyObject will import the test/java/MyObject.java and a 'production' call will call the src/java/MyObject.java?.
Is this kind of directory building safe? Is it common usage?
Where can i read more about this specific flow?

Thanks!

Upvotes: 3

Views: 2205

Answers (1)

AleSod
AleSod

Reputation: 422

This is a result of how Java dependencies work. When running JUnit tests the src/test/java directory is used as the project to be run, src/main/java is treated as a dependency. When java is trying to resolve an import path it has no idea of knowing if the path is from an internal file or a dependency. Therefore it will first try to resolve it within the project and then look at the dependencies. If it finds a match in the project it will not look any further. In the same way, when running the 'production' code src/main/java is used as the main project with no dependency to src/test/java, therefore it will always get the original implementation of MyObject.

Overwriting classes in this manner is technically safe but not a good practice. It would make it unclear if the original implementation is used.

If you want to keep most of the logic of MyObject but override some of it you should create a stub class in src/test/java, ie. MyObjectStub.

Another way of replacing logic logic for testing is to use a mocking library such as Mockito.

Upvotes: 4

Related Questions