FIRSTLY: I am testing legacy code.
I am testing an abstract class we will call Class A.
Class A has Field of type Class B. Class B is a child of Abstract base class we will call B_Base.
MY PROBLEM: In a method of class A, the instance of class B calls a method in B_Base.
I have tried mocking a B class and then replacing the Field with the mocked B Class, however, everytime it runs the parent method, there is a NullPointerException in the Mockito.when() method, meaning the parent B_Base class is NOT mocked.
Here is an idea of what the code looks like.
public abstract class A { //this is the class Im testing.
public B bInstance;
public boolean methodIAmTesting {
int hello = bInstance.method_Only_In_B_Base();
...
}
}
The test:
public class TestClass extends A {
//here is the constructor etc..
@Test
public void test1 {
TestClass x = new TestClass();
bInstance = Mockito.mock(B.class);
// ERROR IS HERE V
Mockito.when(bInstance.method_Only_In_B_Base()).thenReturn(50);
Assert.assertTrue(x.methodIAmTesting());
}
}
As J L mentioned, you've actually got two instances kicking around, because your TestClass extends A.
What you have:
public class TestClass extends A {
@Test public void test1() {
Class TestClass x = new TestClass();
bInstance = Mockito.mock(B.class);
// ...
}
}
What you want:
public class TestClass extends A {
@Test public void test1 {
Class TestClass x = new TestClass();
x.bInstance = Mockito.mock(B.class); // <-- replace bInstance on x
// ...
}
}
JUnit creates an instance of your test class automatically, so when you call x = new TestClass()
you're creating a separate instance for test, and your call for bInstance = mock(B.class)
is setting the mock on the instance that JUnit creates rather than the x
instance you create.
Note that it's very unusual to have a JUnit test class subclass the system under test. Consider a design like this instead:
@RunWith(JUnit4.class)
public class ATest {
private static class TestClass extends A {
// ...
}
@Test public void test1 {
Class TestClass x = new TestClass();
x.bInstance = Mockito.mock(B.class);
// ...
}
}