2011-12-12 2 views
2

과제에 대한 테스트를 만들면서 이상한 점을 발견했습니다. AssertionError.왜이 어설 션인지 어설 션은 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 소스 코드를 파고 난 단지 전화 assertThat 그 JUnit을 발견 한 내가 간단한 경우에 도착할 때까지

나는 그것을 변경 매처에서 일치합니다.

이 경우의 일치 방법은 :

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

인수는 "P2"이어야하고 객체 "P1"해야하는 경우. , 디버거 검사를 사용하여, areEqual 방법의 비교

결과를 (그것은 Hamcrest repository에서 찾아 볼 수있다)

은 다음과 같습니다 당신이 볼 수있는

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

그래서, 코드가 마지막에 도달한다 다른 상태와 당신의 도움

,536에 대한 true ( p2.equals(p1)), 그러나 equalTo(p1).matches(p2) 반환 false

감사를 반환

답변

7

p2.equals(p1)true (으)로 반환하는 이유는 무엇입니까? Permutation 클래스에서 equals을 재정의하지 않았으므로 기본적으로 참조 ID를 사용합니다. 치환을 할 때 평등의 의미를 나타내려면 equals (그리고 대체로 equals와 일치시키기 위해 hashCode)을 오버라이드해야합니다.

편집 : 이제 더 많은 코드를 게시 했으므로 진행 상황이 명확 해집니다. 는 정규 표현이 사용하게 될 것입니다, 이는하지 재정 Object.equals을 수행

public boolean equals(Permutacion permutation){ 

그건 : 귀하의 equals 메소드는이 서명이 있습니다. 대신, 과부하로 - 디버거 검사에서 호출되는 새로운 방법을 도입합니다. 당신이 작성하는 경우 :

Object o1 = p1; 

p2.equals(o1)도 디버거에서 false을 보여줍니다 - 그리고는 정규 표현이 무엇을하고 있는지 효과적이다.

@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를 오버라이드 (override) : 귀하의 equals 메소드는 같은 것을 보일 것입니다.또한)

:

  • 중 하나가 elements가 null의 경우 경우를 고려, 또는
  • 평등 당신이 방어를 만들기하지 않는 것처럼
  • 최종 클래스에 정의하기 간단 생성자에서 그것을 확인 목록의 복사본은 건설 후 발신자가 변형시킬 수 있습니다. 예를 들어 순열을지도의 키로 사용하면 문제가 발생할 수 있습니다.
+0

죄송합니다. 질문에 추가하는 것을 잊었지만 가지고 있습니다. 어쨌든, 내가 게시 한 결과는 이클립스의 표현식 창에서 나온 것인데, 단지 추측이 아닙니다. –

+0

@JuanGuerrero : 아니요, 당신은 * equals (Object)를 오버라이드하지 않았습니다. 편집 할 것입니다. –

+0

고마워, 효과가 있었다. 귀하의 답변을 해결 된 것으로 표시하겠습니다. –

관련 문제