[英]Mockito not mocking private variables using @Spy
I am attempting to mock a private instance variable listOfStrings
using Mockito's @Spy
annotation. 我正在尝试使用Mockito的
@Spy
注释模拟私有实例变量listOfStrings
。
@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. 它似乎并没有嘲笑实例变量,显然抛出了
NullPointerException
。
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). Mockito
为您实例化该模拟,但是您要用自己的myObject
实例替换该模拟,这会导致NPE(显然,新实例化的对象中的listOfStrings
为null)。
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()
. 您忘记了在
Mockito.initMocks(this)
内部调用Mockito.initMocks(this)
before()
。 Also, you don't need to initialize myObject
because mockito
will initialize it for you. 另外,您不需要初始化
myObject
因为mockito
会为您初始化它。
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. 我还要指出的是,您的测试实际上并没有做任何事情,因为您没有断言或验证任何事情,您只是在调用
MyObject.call ListOfString()
方法。
Did you try With Java Reflection. 您是否尝试过使用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
listOfStrings
That will avoid the null pointer exception. 这样可以避免空指针异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.