Reputation: 1600
I have a class with a dependency like this:
public class Subject {
private Dependency dep;
public Subject(Dependency d) {
this.dep = d;
}
public Result test() {
return dep.validate();
}
}
My Dependency class is actually a base class. It looks like this:
public Class Dependency extends Base {
void method1() {
}
}
The Base class is an abstract class like this:
public abstract class Base {
protected abstract method1() {
}
//This is the method I want to mock
public Result validate() {
}
}
Now, I am trying to test my class Subject
:
public class SubjectTest {
@Mock
private Dependency dep;
private Subject subject;
@Before
public void setup() {
initMocks(this);
subject = new Subject(dep);
}
@Test
public void test() {
when(dep.validate()).thenReturn(Result.VALID); //validate is a super class method
subject.test();
}
}
When I try to mock the method in when(dep.validate()).thenReturn(Result.VALID)
, it actually calls the real super class method and throws a NullPointerException.
How can I solve this issue? I am aware that Composition is to be favored over inheritance, but I have no control over the Dependency class. So, I cannot go and change it.
My team does not favor use of PowerMockito either. So, I cannot use that as well.
Upvotes: 0
Views: 2034
Reputation: 42541
Probably you've messed something in a setup. I've tried to reproduce your case and it works in my setup:
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;
enum Result {
VALID, INVALID;
}
abstract class Base {
protected abstract void method1();
public Result validate() {
return Result.INVALID;
}
}
class Dependency extends Base {
public void method1() {
}
}
class Subject {
private Dependency dep;
public Subject(Dependency d) {
this.dep = d;
}
public Result test() {
return dep.validate();
}
}
public class SampleTest {
private Dependency dep = Mockito.mock(Dependency.class);
private Subject subject;
@Test
public void testMe() {
subject = new Subject(dep);
when(dep.validate()).thenReturn(Result.VALID); //validate is a super class method
Result result = subject.test();
assertThat(result, equalTo(Result.VALID));
}
}
All-in-all Mockito should support such a use case without any issues.
I suspect that its something with "initMocks"/ or maybe @Mock
annotation that requires a special runner/extension if you're on JUnit 5, which is not shown in a question.
I've intentionally avoided these "advanced" features in the example above to create a minimal reproducible example. Please check this code and update whether it works for you.
P.S.: used Mockito-core:3.3.3 for the test
Upvotes: 1
Reputation: 190
Can't reproduce the error with Java:8, junit:4.12 and mockito:2.1.0, posted code behaves correctly. Double check the versions, maybe.
Upvotes: 1