[英]Mockito not mocking private variables using @Spy
我正在嘗試使用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();
}
}
和
public class MyObject {
private List<String> listOfStrings;
public void callListOfStrings() {
listOfStrings.stream().forEach(System.out::println);
}
}
它似乎並沒有嘲笑實例變量,顯然拋出了NullPointerException
。
myObject = new MyObject();
-這是問題的根源。 Mockito
為您實例化該模擬,但是您要用自己的myObject
實例替換該模擬,這會導致NPE(顯然,新實例化的對象中的listOfStrings
為null)。
那應該如何工作:
@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();
}
}
輸出:
test
test2
您忘記了在Mockito.initMocks(this)
內部調用Mockito.initMocks(this)
before()
。 另外,您不需要初始化myObject
因為mockito
會為您初始化它。
我還要指出的是,您的測試實際上並沒有做任何事情,因為您沒有斷言或驗證任何事情,您只是在調用MyObject.call ListOfString()
方法。
您是否嘗試過使用Java Reflection。 我認為您需要避免空指針異常。
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();
}
}
您可以為私有變量分配一個值
listOfStrings
這樣可以避免空指針異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.