EasyMock - 改变equals()和其他Object方法的行为

时间:2010-06-09 15:53:20

标签: java equals easymock

EasyMock文档很清楚

  

对于使用EasyMock创建的模拟对象,无法更改三个对象方法equals(),hashCode()和toString()的行为,即使它们是创建模拟对象的接口的一部分。

我正在尝试测试的代码使用equals()来比较我的模拟对象。我想做一些像

这样的事情
expect(mock.equals(obj)).andReturn(false);

当我这样做时,我得到一个IllegalStateException。考虑到文档的内容,并不奇怪。

有没有人对替代方法有任何建议?还有另一种方法可以控制模拟对象在调用equals()时返回的内容吗?我想我可以创建一个覆盖equals()

的子类
class FooImplOverrideEquals extends FooImpl {
    public boolean equals;
    public boolean equals(Object obj) { return equals; }
}
FooImplOverrideEquals mock = createMock(FooImplOverrideEquals.class);
mock.equals = false; // instead of expect(mock.equals(obj)).andReturn(false);

但这似乎不优雅。我觉得我缺少一些重要的东西(比如EasyMock不允许你覆盖那些对象方法的原因)。有更好的解决方案吗?

2 个答案:

答案 0 :(得分:4)

许多模拟库不支持这一点,因为它通常是一个坏主意。如果你正在做一个equals()比较,那么你有一个值对象,而不是一个真正的协作者,你最好使用一个真实的实例。如果你使用equals()来表示其他一些概念(isBestFriendsWith(other)),那么你可以在适当的时候存根。

答案 1 :(得分:3)

您无法更改equals的行为,但您可以使用Comparator来实现自定义或部分比较。

然后您可以使用以下方法在EasyMock期望中使用比较器:

EasyMock.cmp

例如,如果您有一个具有名称和年龄实例变量的Person类,并且您只对比较名称感兴趣:

public class Person {
    String name;
    int age;

public boolean equals(Object obj) {
        // the equals method compares the name and the age, but we are interested only in                  
        // comparing the name
        // other not-null checks...
        Person other = (Person) obj;
        if (this.age != other.age) {
            return false;
        }
        if (other.name != null) {
            return false;
        }
        return true;
    }
}

public class PersonComparator implements Comparator<Person> {
        @Override
        public int compare(Person person1, Person person2) {
            //compare only the name
            if (person1.getName().equals(person2.getName())) {
                return 0;
            }
            return -1;
        }

}

以这种方式使用EasyMock.expect:

PersonComparator nameComparator = new PersonComparator();

Person person = new Person("Ana"); //the age doesn't matter

Person expectedPerson = EasyMock.cmp(comparisonPerson, nameComparator, LogicalOperator.EQUAL);

EasyMock.expect(personService.authenticate(expectedPerson)).andReturn(true);