2011-12-12 77 views
2

为作业创建测试,我收到一个奇怪的AssertionError异常。为什么这个assertion引发AssertionError?

我已经改变了它,直到我到了一个简单的例子:

List<Integer> elements= new ArrayList<Integer>(); 
elements.add(1); 
elements.add(2); 
elements.add(3); 

Permutation p2 = new Permutation(elements); 
Permutation p1 = new Permutation(elements); 

assertThat(p2, equalTo(p1)); 

Permutation.java:

public class Permutation { 

    private List<Integer> elements; 

    public Permutation(List<Integer> elements) { 
    this.elements = elements; 
    } 

public boolean equals(Permutacion permutation){ 
    if (this.elements.size() != permutation.elements.size()){ 
    return false; 
    } 

    Iterator<Integer> iterThis = this.elements.iterator(); 
    Iterator<Integer> iterOther = permutation.elements.iterator(); 
    while (iterThis.hasNext() && iterOther.hasNext()){ 
    if (iterThis.next() != iterOther.next()){ 
     return false; 
    } 
    } 

    return true; 

} 

两个JUnit和hamcrest源代码挖我发现,JUnit的assertThat只有电话在匹配器上匹配。

在这种情况下的匹配方法是:

public boolean matches(Object arg) { 
    return areEqual(arg, object); 
} 

private static boolean areEqual(Object o1, Object o2) { 
    if (o1 == null) { 
     return o2 == null; 
    } else if (o2 != null && isArray(o1)) { 
     return isArray(o2) && areArraysEqual(o1, o2); 
    } else { 
     return o1.equals(o2); 
    } 
} 

其中arg应该是 “P2” 和对象应为 “P1”。

使用调试器的检查,(它可以在Hamcrest repository可以浏览)

在areEqual方法比较的结果是:

"p2 == null"     false 
"p1 != null"     true  
"p2.getClass().isArray()"  false 
"p2.equals(p1)"     true  
"equalTo(p1).matches(p2)"  false 

因此,大家可以看到,代码应达到最后其他条件并返回truep2.equals(p1)),但equalTo(p1).matches(p2)回报false

感谢您的帮助

回答

7

为什么你会期望p2.equals(p1)返回true?您在Permutation类中未覆盖equals,因此它将默认使用引用标识。你需要重写equals(和hashCode,一般来说,匹配等于)来表示排列时的平等含义。

编辑:现在你已经发布了更多的代码,它更清楚发生了什么事情。你的equals方法有此签名:

public boolean equals(Permutacion permutation){ 

覆盖Object.equals,这是匹配将使用什么。它会引入一个新的方法,即调试器检查中调用的方法。如果你写:

Object o1 = p1; 

然后p2.equals(o1)将显示在调试false太 - 这就是有效的什么匹配在做什么。你的equals方法应该是这个样子:

@Override 
public boolean equals(Object other) 
{ 
    if (other == null || other.getClass() != this.getClass()) 
    { 
     return false; 
    } 
    Permutation otherPermutation = (Permutation) other; 

    // List.equals should do the right thing here 
    return elements.equals(otherPermutation.elements); 
} 

(你也应该重写hashCode在对应于这种方式。)

此外:

  • 要么考虑的情况下elements为空,或者在构造
  • 平等是最简单的final类定义
  • 如果你还没有做防御验证它该清单的副本可能会在调用之后被调用者改变;例如,如果您将排列用作地图中的关键点,则可能会导致问题。
+0

对不起,我忘了在问题中添加它,但我已经拥有它。无论如何,我发布的结果来自eclipse的表达式窗口,不仅仅是一个猜测 –

+0

@JuanGuerrero:不,你*没有*覆盖'equals(Object)'。将编辑。 –

+0

谢谢,它的工作。我会将你的答案标记为已解决 –

相关问题