空指针异常取决于Mockito中的语句链接?

时间:2015-05-05 08:14:13

标签: java unit-testing nullpointerexception mockito criteria

我有一个测试方法应该测试以下方法:

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)

为什么呢?我错过了什么?

这是我的测试类:

@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)));
    }
}

1 个答案:

答案 0 :(得分:2)

您必须模仿add的{​​{1}}方法。这是这里发生的事情。在您的第一个版本中,您已经模拟了条件实例。当你调用方法Criteria时它什么都不做并返回add()但是它不会打扰你,因为你没有使用返回值。

但是,您确实在第二个版本中使用null的返回值。为了使它工作,你应该:

  1. 让mockito调用真正的add()方法\
  2. 模拟add()方法,使其返回原始条件
  3. 例如:

    add()

    when(criteria.add(any(Restrictions.class))).thenCallRealMethod();
    

    (我不确定它应该是when(criteria.add(any(Restrictions.class))).thenReturn(criteria) :它应该是Restrictions.class的类