空指针异常取决于 Mockito 中的语句链接?
Null pointer exception depending on statement chaining in Mockito?
我有一个测试方法应该测试以下方法:
public class SelectionVariantUniqueConstraintValidatorImpl implements UniqueConstraintValidator {
private SessionFactory sessionFactory;
@Override
public List<Criteria> buildValidationCriteria(Object entity, Serializable id, String[] propertyNames) {
final SelectionVariant selectionVariant = (SelectionVariant) entity;
final Session session = sessionFactory.getCurrentSession();
final Criteria criteria = session.createCriteria(SelectionVariant.class);
criteria.add(Restrictions.eq("client", selectionVariant.getClient()));
criteria.add(Restrictions.eq("variant.variantName", selectionVariant.getVariant().getVariantName()));
return new ArrayList<Criteria>(Arrays.asList(criteria));
}
@Required
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
运行良好。但是,如果我按如下方式修改这些行:
final Criteria criteria = session.createCriteria(SelectionVariant.class).add(Restrictions.eq("client", selectionVariant.getClient()));
criteria.add(Restrictions.eq("variant.variantName", selectionVariant.getVariant().getVariantName()));
我会得到:
java.lang.NullPointerException
at com.innflow.ebtam.dao.hibernate.variant.SelectionVariantUniqueConstraintValidatorImpl.buildValidationCriteria(SelectionVariantUniqueConstraintValidatorImpl.java:35)
为什么?我错过了什么?
这是我的测试class:
@RunWith(MockitoJUnitRunner.class)
public class SelectionVariantUniqueConstraintValidatorImplTest {
SelectionVariantUniqueConstraintValidatorImpl selectionVariantUniqueConstraintValidator
= new SelectionVariantUniqueConstraintValidatorImpl();
@Mock
private SessionFactory sessionFactory;
@Mock
private Session session;
@Mock
private Criteria criteria;
@Before
public void setUp() throws Exception {
selectionVariantUniqueConstraintValidator.setSessionFactory(sessionFactory);
}
@Test
public void testBuildValidationCriteria() throws Exception {
Mockito.when(sessionFactory.getCurrentSession()).thenReturn(session);
Mockito.when(session.createCriteria(SelectionVariant.class)).thenReturn(criteria);
SelectionVariant selectionVariant = new SelectionVariant();
Client client = new ClientBuilder().businessKey("HPD").description("desc").version(0).id(1L).build();
selectionVariant.setClient(client);
selectionVariantUniqueConstraintValidator.buildValidationCriteria(selectionVariant, null, null);
Mockito.verify(criteria,Mockito.atLeastOnce()).add(Restrictions.eq("client", Mockito.any(Client.class)));
}
}
您必须模拟 Criteria
的 add
方法。这是这里发生的事情。在您的第一个版本中,您模拟了条件实例。当您调用方法 add()
时,它什么都不做,returns null
但它不会打扰您,因为您不使用 return 值。
然而,您在第二个版本中确实使用了 add()
的 return 值。为了使其正常工作,您应该:
- 制作 mockito 以调用真正的
add()
方法 \
- mock
add()
方法使其符合 return 原始标准
例如:
when(criteria.add(any(Restrictions.class))).thenCallRealMethod();
或
when(criteria.add(any(Restrictions.class))).thenReturn(criteria)
(不确定应该是Restrictions.class
:应该是Restrictions.eq()
的class)
我有一个测试方法应该测试以下方法:
public class SelectionVariantUniqueConstraintValidatorImpl implements UniqueConstraintValidator {
private SessionFactory sessionFactory;
@Override
public List<Criteria> buildValidationCriteria(Object entity, Serializable id, String[] propertyNames) {
final SelectionVariant selectionVariant = (SelectionVariant) entity;
final Session session = sessionFactory.getCurrentSession();
final Criteria criteria = session.createCriteria(SelectionVariant.class);
criteria.add(Restrictions.eq("client", selectionVariant.getClient()));
criteria.add(Restrictions.eq("variant.variantName", selectionVariant.getVariant().getVariantName()));
return new ArrayList<Criteria>(Arrays.asList(criteria));
}
@Required
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
运行良好。但是,如果我按如下方式修改这些行:
final Criteria criteria = session.createCriteria(SelectionVariant.class).add(Restrictions.eq("client", selectionVariant.getClient()));
criteria.add(Restrictions.eq("variant.variantName", selectionVariant.getVariant().getVariantName()));
我会得到:
java.lang.NullPointerException
at com.innflow.ebtam.dao.hibernate.variant.SelectionVariantUniqueConstraintValidatorImpl.buildValidationCriteria(SelectionVariantUniqueConstraintValidatorImpl.java:35)
为什么?我错过了什么?
这是我的测试class:
@RunWith(MockitoJUnitRunner.class)
public class SelectionVariantUniqueConstraintValidatorImplTest {
SelectionVariantUniqueConstraintValidatorImpl selectionVariantUniqueConstraintValidator
= new SelectionVariantUniqueConstraintValidatorImpl();
@Mock
private SessionFactory sessionFactory;
@Mock
private Session session;
@Mock
private Criteria criteria;
@Before
public void setUp() throws Exception {
selectionVariantUniqueConstraintValidator.setSessionFactory(sessionFactory);
}
@Test
public void testBuildValidationCriteria() throws Exception {
Mockito.when(sessionFactory.getCurrentSession()).thenReturn(session);
Mockito.when(session.createCriteria(SelectionVariant.class)).thenReturn(criteria);
SelectionVariant selectionVariant = new SelectionVariant();
Client client = new ClientBuilder().businessKey("HPD").description("desc").version(0).id(1L).build();
selectionVariant.setClient(client);
selectionVariantUniqueConstraintValidator.buildValidationCriteria(selectionVariant, null, null);
Mockito.verify(criteria,Mockito.atLeastOnce()).add(Restrictions.eq("client", Mockito.any(Client.class)));
}
}
您必须模拟 Criteria
的 add
方法。这是这里发生的事情。在您的第一个版本中,您模拟了条件实例。当您调用方法 add()
时,它什么都不做,returns null
但它不会打扰您,因为您不使用 return 值。
然而,您在第二个版本中确实使用了 add()
的 return 值。为了使其正常工作,您应该:
- 制作 mockito 以调用真正的
add()
方法 \ - mock
add()
方法使其符合 return 原始标准
例如:
when(criteria.add(any(Restrictions.class))).thenCallRealMethod();
或
when(criteria.add(any(Restrictions.class))).thenReturn(criteria)
(不确定应该是Restrictions.class
:应该是Restrictions.eq()
的class)