即使模拟被激活,Mockito 也会模拟投掷 NPE
Mockito mock throwing a NPE even when the mocks are activated
我正在尝试模拟调用 baseUtils.getIdentificationType(id.getType().getName())
但实例 baseUtils
始终为空,因此在调用该方法时抛出 NPE。我嘲笑 baseUtils
并使用 Mockito.initMocks(this)
Base class
class Base {
@Inject
protected BaseUtils baseUtils;
protected void populateIdentification(Person person, final List<Id> issuedIds) {
List<Identification> identificationList = new ArrayList<>();
if (issuedIds != null && issuedIds.size() > 0) {
for (Id id : issuedIds) {
Identification identification = new Identification();
// BELOW CALL TO MOCK BUT baseUtils returns null hence NPE in the test
String idType = baseUtils.getIdentificationType(id.getType().getName());
if (idType != null) {
identification.setType(idType);
} else {
identification.setTypeOther(id.getType().getName());
}
identification.setNumber(issuedId.getId());
if (issuedId.getCountryCode() != null) {
CountryCodeEnum codeEnum = CountryCodeEnum.valueOf(govtIssuedId.getCountryCode());
identification.setCountry(codeEnum.getName());
}
identificationList.add(identification);
}
person.setIdentificationList(identificationList);
}
}
}
Child.java
class Child extends Base {
...
}
BaseUtils.java
@Component
public class BaseUtils {
private Map<String, String> idToIdType;
public BaseUtils() {
idToIdType = new HashMap<>();
idToIdType.put("ID1", "A");
idToIdType.put("ID2", "B");
idToIdType.put("ID3", "C");
}
public String getIdentificationType(String documentType) {
if (idToIdType.containsKey(documentType)) {
return idToIdType.get(documentType);
}
return null;
}
}
TEST
@RunWith(MockitoJUnitRunner.class)
public class ChildTest {
@Mock
private BaseUtils baseUtils;
@InjectMocks
Child child = new Child();
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void populateIdentificationTest() {
Child child = new Child();
Person person = new Person();
person.setId("ID_123456");
UserData userData = createUserData();
List<IssuedId> issuedIds = userData.getIssuedIds();
doReturn("ABC").when(baseUtils).getIdentificationType(anyString()); //MOCKED CALL
child.populateIdentification(person, issuedIds);
assertNotNull(person.getIdentificationList());
assertNotNull(person.getIdentificationList().get(0).getNumber());
}
}
我已经查看了其他问题,这就是它在那里完成的方式,所以不确定我没有遵循什么。一些帮助将不胜感激:)
我认为问题出在这里:
您使用 @InjectMocks Child child = new Child();
注入您的 BaseUtils
Mock。但是在您的 @Test
中,您创建了一个 Child
的新实例。不要那样做。使用您在 @InjectMocks Child child = new Child();
.
中创建的 Child
实例
我正在尝试模拟调用 baseUtils.getIdentificationType(id.getType().getName())
但实例 baseUtils
始终为空,因此在调用该方法时抛出 NPE。我嘲笑 baseUtils
并使用 Mockito.initMocks(this)
Base class
class Base {
@Inject
protected BaseUtils baseUtils;
protected void populateIdentification(Person person, final List<Id> issuedIds) {
List<Identification> identificationList = new ArrayList<>();
if (issuedIds != null && issuedIds.size() > 0) {
for (Id id : issuedIds) {
Identification identification = new Identification();
// BELOW CALL TO MOCK BUT baseUtils returns null hence NPE in the test
String idType = baseUtils.getIdentificationType(id.getType().getName());
if (idType != null) {
identification.setType(idType);
} else {
identification.setTypeOther(id.getType().getName());
}
identification.setNumber(issuedId.getId());
if (issuedId.getCountryCode() != null) {
CountryCodeEnum codeEnum = CountryCodeEnum.valueOf(govtIssuedId.getCountryCode());
identification.setCountry(codeEnum.getName());
}
identificationList.add(identification);
}
person.setIdentificationList(identificationList);
}
}
}
Child.java
class Child extends Base {
...
}
BaseUtils.java
@Component
public class BaseUtils {
private Map<String, String> idToIdType;
public BaseUtils() {
idToIdType = new HashMap<>();
idToIdType.put("ID1", "A");
idToIdType.put("ID2", "B");
idToIdType.put("ID3", "C");
}
public String getIdentificationType(String documentType) {
if (idToIdType.containsKey(documentType)) {
return idToIdType.get(documentType);
}
return null;
}
}
TEST
@RunWith(MockitoJUnitRunner.class)
public class ChildTest {
@Mock
private BaseUtils baseUtils;
@InjectMocks
Child child = new Child();
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void populateIdentificationTest() {
Child child = new Child();
Person person = new Person();
person.setId("ID_123456");
UserData userData = createUserData();
List<IssuedId> issuedIds = userData.getIssuedIds();
doReturn("ABC").when(baseUtils).getIdentificationType(anyString()); //MOCKED CALL
child.populateIdentification(person, issuedIds);
assertNotNull(person.getIdentificationList());
assertNotNull(person.getIdentificationList().get(0).getNumber());
}
}
我已经查看了其他问题,这就是它在那里完成的方式,所以不确定我没有遵循什么。一些帮助将不胜感激:)
我认为问题出在这里:
您使用 @InjectMocks Child child = new Child();
注入您的 BaseUtils
Mock。但是在您的 @Test
中,您创建了一个 Child
的新实例。不要那样做。使用您在 @InjectMocks Child child = new Child();
.
Child
实例