1

I have an application I want to test:

import foo.ExtClass;
public class App {
  public static void main(String[] args) {
     ExtClass ext = new ExtClass();
     ...
  }
}

I want to write a unit test for this application, however I do not want to use the foo.ExtClass, but use another mock implementation for the class.

Normally I would use a factory to instantiate the class according to some configuration that can be controlled in the unit test. However, in this case, I cannot modify the tested app.

I was thinking in the direction of writing a custom class loader to load the mock class instead of the real class - not sure if this is possible without any modification to the tested app, and how.

Y.L
  • 694
  • 12
  • 26
  • Well, if you create a new class for the testing, using JUnit or else, you just need to instantiate the `ExtClass` with the implementation you want in that class. – AxelH May 07 '18 at 10:36
  • You can use the Java framework Reflection to load any Java-class from the path of the class loader. It's possible to ask for available methods in the class, and even call methods with the type-correct parameters. There are several online tutorials Java Reflection. – Flying Dutchman May 07 '18 at 10:37
  • 1
    If you jar your version of `foo.ExtClass` and put it in front in the class path specification (i.e. `java -cp 'extClass.jar:original.jar' ....`) the classloader should pick up your version before the original one automatically and therefore shadow it. This wont work, however, if your application is already running. If the original class was loaded before by the application loader there is no option to un- or reload it. This only works with custom loaders (assuming they follow the correct propagation model). – Roman Vottner May 07 '18 at 11:22

2 Answers2

1

As an option you can use custom classloader, which will substite your class with a testing one. So basically instead of loading ExtClass from your app package, your classloader will load the same class from your testing package with the mock implementation.

Here is an example:

How to replace classes in a running application in java ?

Also there is very usefull tutorial: https://zeroturnaround.com/rebellabs/reloading-objects-classes-classloaders/

Ruslan Akhundov
  • 2,178
  • 4
  • 20
  • 38
0

The approach I finally used: Created a separate project with my mock implementation of foo.ExtClass, and the unit tests.

This way the mock implementation appeared in the classpath before the real implementation, and the original (tested) project remained untouched.

Y.L
  • 694
  • 12
  • 26