Reputation: 8008
I am using mockito for my unit tests. Consider the following snippet
ThirdPartyClass tpo = mock(ThirdPartyClass.class);
doNothing().when(tpo).someMethod();
ThirdPartyClass
is from a third party jar, lets say tp.jar
. Now tp.jar
is not an uber jar. Here is what ThirdPartyClass
looks like
class ThirdPartyClass
{
SomeOtherClass memberObject;
public ThirdPartyClass(){}
/*Rest of the code*/
}
Now, when i try to run my unit tests, i get java.lang.ClassNotFoundException
for SomeOtherClass
. Remember that tp.jar
is not an uber jar so it makes sense that SomeOtherClass
is not in my classpath.
But why is mockito not able to handle this transitive dependency? Is there any way to ignore all transitive dependencies?
Upvotes: 1
Views: 1798
Reputation: 10047
"Only mock types that you own" is the way to go here.
One reason for that is exactly what you describe: the test set up becomes too complicated, e.g. because of dependencies.
So instead of mocking the ThirdPartyClass
, you create some sort of Adapter and then mock that class.
interface ThirdPartyAdapter {
void someMethod(); // only put method here that you really use
}
And then mock that thing instead:
ThirdPartyAdapter tpo = mock(ThirdPartyAdapter.class);
doNothing().when(tpo).someMethod();
And in production, delegate to the ThirdPartyClass
:
class UsefulThing implements ThirdPartyAdapter {
ThirdPartyClass wrapped;
UsefulThing(ThirdPartyClass wrapped) {
this.wrapped = wrapped;
}
@Override
void someMethod() {
wrapped.someMethod()
}
}
Benefits:
I highly recommend Growing Object Oriented Software by Freeman & Pryce - or check the mockito docks for a quick start.
Upvotes: 7
Reputation: 27976
If you are going to mock ThirdPartyClass
then SomeOtherClass
MUST be on your compile-time and runtime classpath. Without seeing how you are building/running it's difficult to give real help
You need to ensure that all the required classes (jars) are on
If you are using a build tool like Gradle or Maven to build & run then the classpaths, including transitive dependencies, will be managed for you. If you are compiling/running by hand you will need to ensure that the transitive dependencies are on the compile-time & runtime classpaths.
Upvotes: 1
Reputation: 12180
Mockito works by creating a subclass of the class to be mocked. So the class to be mocked has to compile. Could perhaps be solved by adding the jar that contains SomeOtherClass
to your dependency management with scope test
.
Upvotes: 4