Reputation: 1343
I am testing a class using JUnit4 and the target class uses a dependency static method to create an object, here is the relevant snippet of code from the target class:
private static final Dependency DEPENDENCY_CLIENT = Dependency.getInstance();
I know that since version 3.4.0 of Mockito, there is the added ability to mock static methods, for example, I can do something like:
try (MockedStatic<Dependency> mocked = mockStatic(Dependency.class)) {
mocked.when(Dependency::getInstance).thenReturn(dependency);
Dependency test = Dependency.getInstance();
mocked.verify(Dependency::getInstance);
}
The dependency
variable is just a simple mocked version of that class.
However, the class I want to test makes this call in its constructor, so is there a way where I can make my target class call the mocked getInstance()
method during its initialization?
Upvotes: 0
Views: 1382
Reputation: 11464
I'm not exactly sure what problem you are having. The code below works for me (I'm using JUnit 5, but that should make no difference)
@ExtendWith(MockitoExtension.class)
public class MockEg {
static class Dependency {
public static Dependency getInstance() {
return new Dependency();
}
public String getMessage() {
return "I am not a mock";
}
}
static class ClassToTest {
private final Dependency dependency;
public ClassToTest() {
this.dependency = Dependency.getInstance();
}
public String getDependencyMessage() {
return dependency.getMessage();
}
}
@Test
public void aTest() {
try (MockedStatic<Dependency> mocked = mockStatic(Dependency.class)) {
Dependency dependency = mock(Dependency.class);
when(dependency.getMessage()).thenReturn("I am a mock");
mocked.when(Dependency::getInstance).thenReturn(dependency);
ClassToTest c = new ClassToTest();
assertThat(c.getDependencyMessage(), Matchers.is("I am a mock"));
mocked.verify(Dependency::getInstance);
}
}
}
The right way to deal with this situation is to decouple your class from static
s, by introducing an interface which you can mock:
interface DependencyProvider {
Dependency getDependency();
}
class ClassToTest2 {
private final DependencyProvider dependencyProvider;
public ClassToTest2(DependencyProvider dependencyProvider) {
this.dependencyProvider = dependencyProvider;
}
public String getDependencyMessage() {
return dependencyProvider.getDependency().getMessage();
}
}
Upvotes: 1