I am attempting to mock a private instance variable listOfStrings
using Mockito's @Spy
annotation.
@RunWith(MockitoJUnitRunner.class)
public class MyObjectTest {
@InjectMocks
MyObject myObject;
@Spy
List<String> listOfStrings;
@Before
public void before() {
myObject = new MyObject();
}
@Test
public void testCallListOfStrings() {
Mockito.doReturn(new ArrayList().stream()).when(listOfStrings).stream();
myObject.callListOfStrings();
}
}
and
public class MyObject {
private List<String> listOfStrings;
public void callListOfStrings() {
listOfStrings.stream().forEach(System.out::println);
}
}
It does not appear to be mocking the instance variable, throwing a NullPointerException
, obviously.
myObject = new MyObject();
- this is the root of the problem. Mockito
instantiates the mock for you, but you're replacing the mock with your own myObject
instance, what leads to NPE (obviously, the listOfStrings
is null in your newly instantiated object).
That how it should work:
@RunWith(MockitoJUnitRunner.class)
public class MyObjectTest {
// Don't do this with List!
// Type 'List' is an interface and it cannot be spied on.
@Spy
private ArrayList<String> listOfStrings;
@InjectMocks
private MyObject myObject;
@Before
public void before() {
listOfStrings.addAll(List.of("test", "test2"));
}
@Test
public void testCallListOfStrings() {
Mockito.doReturn(new ArrayList().stream()).when(listOfStrings).stream();
myObject.callListOfStrings();
}
}
Output:
test
test2
You forgot to call Mockito.initMocks(this)
inside before()
. Also, you don't need to initialize myObject
because mockito
will initialize it for you.
I would also like to note that your test really isn't doing anything, because you're not asserting or verifying anything, you're just calling the MyObject.call ListOfString()
method.
Did you try With Java Reflection. I think you need to avoid the null pointer exception.
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.runners.MockitoJUnitRunner;
import java.lang.reflect.Field;
import java.util.ArrayList;
@RunWith(MockitoJUnitRunner.class)
public class MyObjectTest {
@InjectMocks
MyObject myObject;
@Before
public void before() {
myObject = new MyObject();
}
@Test
public void testCallListOfStrings() throws NoSuchFieldException, IllegalAccessException {
Field list = myObject.getClass().getDeclaredField("listOfStrings");
list.setAccessible(true); // Suppress Java language access checking
list.set(myObject,new ArrayList<>());
myObject.callListOfStrings();
}
}
You can assign a value for the private variable
listOfStrings
That will avoid the null pointer exception.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.