Java 莫基托说,论点并不完全相同,但它们是一样的吗?

Java 莫基托说,论点并不完全相同,但它们是一样的吗?,java,hibernate,unit-testing,session,mockito,Java,Hibernate,Unit Testing,Session,Mockito,这是我要测试的方法: public class SelectionVariantUniqueConstraintValidatorImpl implements UniqueConstraintValidator { private SessionFactory sessionFactory; @Override public List<Criteria> buildValidationCriteria(Object entity, Serializabl

这是我要测试的方法:

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;
    }
}
这是我在控制台中看到的:

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

criteria.add
的参数不是
客户端
,而是的返回值

SimpleExpression
对象继承了它的.equals方法,因此,由于您在测试中构造了一个新的方法,所以这两个参数并不相等,即使它们包含相同的
客户机

一种比较参数的方法是实现一个
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));
类SimpleExpressionMatcher扩展ArgumentMatcher{
私有SimpleExpression SimpleExpression;
公共SimpleExpressionMatcher(SimpleExpression SimpleExpression){
this.simpleExpression=simpleExpression;
}
@凌驾
公共布尔匹配(对象参数){
@SuppressWarnings({“unchecked”,“rawtypes”})
SimpleExpression otherSimpleExpression=(SimpleExpression)参数;
//以某种方式比较SimpleExpression,可能如下所示:
//this.simpleExpression.toString()等于(其他simpleExpression.toString());
}
}
然后像这样验证:

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));
Matcher Matcher=newsimpleexpressionmatcher(Restrictions.eq(“client”,selectionVariant.getClient());
验证(标准).add(Mockito.argThat(匹配器));

我猜您忘了在客户端中实现equals和hashCode方法。java@RadoslawGrebski添加了equals方法。@TimBiegeleisen我不理解你的句子,抱歉。但是我在问题中添加了更多的信息。@KorayTugay对不起,我不明白你的问题。Mockito.verify(criteria).add(Mockito.any(Client.class))是否未通过测试?否。当我使用Mockito.any(Client.class))测试将成功。客户端类是否实现org.hibernate.criteria.criteria(criteria.add的参数类)?如果没有,我前面评论中的那一行甚至不应该编译。不,它没有实现标准。它确实可以编译。我已经编辑了问题并添加了我是如何进行测试的声明。好的,我不认为这是应该使用Mockito.any的方式-请注意,您可以向criteria.add提供任何对象,您的测试将通过(字面意思是:使用criteria.add尝试它(Restrictions.eq(“not client”,new object()))。这是莫基托奇怪的行为。我建议不要使用你的变体,因为它实际上并不测试你想要的。