문제
테스트 클래스에서는 내 자신의 과부하를 제공하고 싶습니다. assertEquals
특별한 논리로 의존하지 않습니다 Object.equals
. 불행히도, 그것은 내가 선언하자마자 assertEquals
로컬에서 Java는 정적 가져 오기를 찾지 못합니다. org.junit.Assert.*
더 이상.
이것에 대한 방법이 있습니까? 즉, 정적으로 가져온 방법에 추가 과부하를 제공 할 수있는 방법이 있습니까? (다소 명백한 해결책은 방법을 다르게 지명하는 것이지만이 솔루션은 같은 미적 매력을 가지고 있지 않습니다.)
내 테스트 클래스 파일은 다음과 같습니다.
package org.foo.bar;
import static org.junit.Assert.*;
import org.junit.Test;
public class BarTest {
private static void assertEquals(Bar expected, Bar other) {
// Some custom logic to test equality.
}
@Test
public void testGetFoo() throws Exception {
Bar a = new Bar();
assertEquals(42, a.getFoo()); // Error *
}
@Test
public void testCopyConstructor() throws Exception {
Bar a = new Bar();
// Fill a.
Bar b = new Bar(a);
assertEquals(a, b);
}
}
Error *
“방법 assertEquals(Bar, Bar)
유형에서 BarTest
논증에 적용 할 수 없습니다 (int, int)
.”
해결책
이 답변에는 컴파일 오류에 관한 두 섹션이 있고 다른 하나는 Assertequals ()의 사용에 관한 것입니다.
문제는 두 개의 다른 네임 스페이스에 두 가지 assertequals () 메소드가 있다는 것입니다. 하나는 org.junit.assert 네임 스페이스에 있고 다른 하나는 org.foo.bar.bartest 네임 스페이스 (현재 네임 스페이스)에 있습니다.
오류는 컴파일러가 Java 언어 사양으로 선언 된 그림자 규칙. Assert.assertequals ()의 정적 가져 오기는 Bartest 클래스에서 선언 된 Assertequals ()에 의해 섀도 잉됩니다.
수정 (항상 섀도우 선언의 경우)은 FQN (완전히 자격을 갖춘 이름)을 사용하는 것입니다. Junit Assert 클래스의 Assertequals (...)를 사용하려는 경우 사용하십시오.
org.junit.Assert.assertEquals(...)
그리고 선언을 사용해야 할 때 간단히 사용하십시오.
assertEquals(...)
바르 테스트에서만 그림자가있는 곳. Assert.assertequals () 또는 Bartest.asserequals ()만을 필요로하는 다른 모든 클래스에서 Assert 또는 Bartest를 가져올 수 있습니다 (다른 곳에서 Bartest를 가져올 필요는 없지만 그럼에도 불구하고 언급했습니다).
그림자가 없으면 클래스 또는 정적 방법을 단순히 가져 와서 FQN없이 사용할 수 있습니다.
생각할 추가 물건
assert.assertequals ()는 인수 클래스의 equals () 메소드를 내부적으로 사용합니다. 테스트 사례에서 AsserTequals ()를 선언하면 equals () 메소드의 유형을 일관되게 구현하고 사용해야하므로 건조 원칙을 위반합니다. 소스 코드에 두 가지 다른 구현을 넣고 단위 테스트에서 혼란을 유발할 수 있습니다.
가장 좋은 방법은 막대에서 equals ()를 구현 한 다음 테스트 사례에서 assert.assertequals ()를 사용하는 것입니다. 이미 가지고 있다면, 당신은 bartest.assertequals ()가 필요하지 않습니다. Assertequals ()의 의사 코드는 다음과 비슷합니다.
- 두 인수가 모두 null이라면 True를 반환하십시오.
- 만약에 예상되는 null이 아니고 equals ()를 호출합니다. 예상되는 통과 실제 논쟁으로. 객체가 같으면 true를 반환하십시오.
- 객체가 같지 않으면 AssertionError를 형식화 된 메시지로 던지십시오.
다른 팁
특정 전화의 예제를위한 하나의 가능한 솔루션 assertEquals(Bar, Bar)
단위 테스트에서는 다음과 같이 정적 메소드를 제공하는 클래스로 클래스를 확장하는 것입니다.
class BarAssert extends Assert {
public static void assertEquals(Bar expected, Bar other) {
// Some custom logic to test equality.
}
}
그런 다음 포함 할 수 있습니다 import static BarAssert.assertEquals;
사용자 정의 로직을 사용하십시오.
이것이 질문에 직접 대답하지 않고 당신의 모범을 더 목표로한다는 사과드립니다. 질문에 첨부 된 내 의견에 따라이 접근법에 대해 권장합니다.
유일한 방법은 하나 이상의 자격을 갖추는 것입니다.
import static org.junit.Assert.*;
import org.junit.Test;
public class BarTest {
private static void assertEquals(Bar expected, Bar other) {
// Some custom logic to test equality.
}
@Test
public void testGetFoo() throws Exception {
Bar a = new Bar();
org.junit.Assert.assertEquals(42, a.getFoo());
}
}
this.assertEquals(a,b);
또는
BarTest.assertEquals(a,b);
나는 정적 방법 임에도 불구하고, 당신은 그것을 사용하기 위해 인스턴스가 있어야하기 때문에 첫 번째 것과 함께 갈 것입니다 (개인). this
미래의 혁신의 기발한 영향을받지 않을 것입니다.