Mockito说争论并不完全相同,但他们是?

时间:2015-05-05 07:31:23

标签: java hibernate unit-testing session 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;
    }
}

这是我的考验:

@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", selectionVariant.getClient()));
    }
}

这就是我在控制台中看到的:

Argument(s) are different! Wanted:
criteria.add(
    client=Client{id=1, businessKey='HPD', description='desc', version=0}
);
-> at com.innflow.ebtam.dao.hibernate.variant.SelectionVariantUniqueConstraintValidatorImplTest.testBuildValidationCriteria(SelectionVariantUniqueConstraintValidatorImplTest.java:48)
Actual invocation has different arguments:
criteria.add(
    client=Client{id=1, businessKey='HPD', description='desc', version=0}
);
-> at com.innflow.ebtam.dao.hibernate.variant.SelectionVariantUniqueConstraintValidatorImpl.buildValidationCriteria(SelectionVariantUniqueConstraintValidatorImpl.java:36)

我错过了什么?

编辑:

Client.java中的

equals方法如下:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || (getClass() != o.getClass() && !(o instanceof Client))) return false;

    Client client = (Client) o;

    if (businessKey != null ? !businessKey.equals(client.getBusinessKey()) : client.getBusinessKey() != null)
        return false;

    return true;
}

编辑:

Client.java中的

hashCode方法:

@Override
public int hashCode() {
    return businessKey != null ? businessKey.hashCode() : 0;
}

编辑:

这使测试工作:

Mockito.verify(criteria,Mockito.atLeastOnce()).add(Restrictions.eq("client", Mockito.any(Client.class)));

1 个答案:

答案 0 :(得分:5)

criteria.add的参数不是Client,而是Restrictions.eq的返回值,SimpleExpression

SimpleExpressionObject继承了它的.equals-method,所以既然你在测试中构造了一个新的,那么这两个参数不相等,即使它们包含相同的Client

比较你想要的方式的方法就是像这样实现org.hamcrest.Matcher

class SimpleExpressionMatcher extends ArgumentMatcher<SimpleExpression> {
    private SimpleExpression simpleExpression;

    public SimpleExpressionMatcher(SimpleExpression simpleExpression) {
        this.simpleExpression = simpleExpression;
    }

    @Override
    public boolean matches(Object argument) {
        @SuppressWarnings({"unchecked", "rawtypes"})
        SimpleExpression otherSimpleExpression = (SimpleExpression) argument;
        // somehow compare the SimpleExpressions, possibly like this:
        // this.simpleExpression.toString().equals(otherSimpleExpression.toString());
    }
}

然后验证如下:

 Matcher<SimpleExpression> matcher = new SimpleExpressionMatcher(Restrictions.eq("client", selectionVariant.getClient()));
 Mockito.verify(criteria).add(Mockito.argThat(matcher));