JUnit 테스트 케이스 에서 목록 사이에 동등 어설 션을 어떻게 만들 수 있습니까? 평등은 목록의 내용 사이에 있어야합니다.
예를 들면 다음과 같습니다.
List<String> numbers = Arrays.asList("one", "two", "three");
List<String> numbers2 = Arrays.asList("one", "two", "three");
List<String> numbers3 = Arrays.asList("one", "two", "four");
// numbers should be equal to numbers2
//numbers should not be equal to numbers3
답변
나는 이것이 몇 년 전에 요청되었다는 것을 알고 있습니다. 아마도이 기능은 주변에 없었습니다. 그러나 이제는 이렇게하는 것이 쉽습니다.
@Test
public void test_array_pass()
{
List<String> actual = Arrays.asList("fee", "fi", "foe");
List<String> expected = Arrays.asList("fee", "fi", "foe");
assertThat(actual, is(expected));
assertThat(actual, is(not(expected)));
}
hamcrest와 함께 최신 버전의 Junit을 설치 한 경우 다음 가져 오기를 추가하십시오.
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
http://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat(T, org.hamcrest.Matcher)
http://junit.org/junit4/javadoc/latest/org/hamcrest/CoreMatchers.html
http://junit.org/junit4/javadoc/latest/org/hamcrest/core/Is.html
답변
문자열로 변환하고 비교하지 마십시오. 이것은 성능에 좋지 않습니다. junit에는 Corematchers 안에 이에 대한 matcher가 있습니다.hasItems
List<Integer> yourList = Arrays.asList(1,2,3,4)
assertThat(yourList, CoreMatchers.hasItems(1,2,3,4,5));
이것이 목록의 요소를 확인하는 더 좋은 방법입니다.
답변
이것은 JUnit 4.3 이하에 적합한 레거시 답변입니다. 최신 버전의 JUnit은 assertThat 메소드에 내장 된 읽기 가능한 실패 메시지를 포함합니다. 가능하면이 질문에 대한 다른 답변을 선호하십시오.
List<E> a = resultFromTest();
List<E> expected = Arrays.asList(new E(), new E(), ...);
assertTrue("Expected 'a' and 'expected' to be equal."+
"\n 'a' = "+a+
"\n 'expected' = "+expected,
expected.equals(a));
@Paul이이 답변에 대한 그의 언급에서 언급했듯이, 두 개의 List
s는 같습니다.
지정된 객체도리스트 인 경우에만 두리스트의 크기가 동일하고 두리스트의 모든 해당 요소 쌍이 동일합니다. (두 요소
e1
와e2
같으면 동일합니다(e1==null ? e2==null : e1.equals(e2))
.) 즉, 두 요소가 동일한 순서로 동일한 요소를 포함하는 경우 두 목록이 동일하게 정의됩니다. 이 정의는 equals 메소드가List
인터페이스의 다른 구현에서 올바르게 작동하도록합니다 .
인터페이스 의 JavaDoc을List
참조하십시오 .
답변
assertEquals(Object, Object)
JUnit4에서 / JUnit을 5 assertThat(actual, is(expected));
Hamcrest에서 단지 모두로 작동 다른 답변에서 제안 equals()
하고 toString()
비교 객체의 클래스 (깊이)에 대한 오버라이드된다.
어설 션의 동등성 테스트 equals()
와 테스트 실패 메시지 toString()
가 비교 된 개체 에 의존하기 때문에 중요 합니다.
들어 내장과 같은 클래스 String
, Integer
등등 … 이러한 재정 등의 문제없이 모두 equals()
와 toString()
. 그래서 주장 완벽하게 유효 List<String>
또는 List<Integer>
과 assertEquals(Object,Object)
.
그리고이 문제에 대해 : equals()
JUnit 테스트에서 어설 션을 쉽게 만들 수있을뿐만 아니라 객체 평등 측면에서 의미가 있기 때문에 클래스에서 재정의해야합니다 .
어설 션을 쉽게 만들려면 다른 방법이 있습니다.
모범 사례로 어설 션 / 매칭 라이브러리를 선호합니다.
다음은 AssertJ 솔루션입니다.
org.assertj.core.api.ListAssert.containsExactly()
그것은 당신이 필요로하는 것입니다 : 그것은 실제 그룹이 javadoc에 명시된 순서대로 주어진 값을 포함하고 다른 것을 포함하지 않는지 확인합니다.
Foo
요소를 추가하고 얻을 수 있는 클래스를 가정하십시오 . 그에
대한 단위 테스트 Foo
는 두 목록이 동일한 내용을 가지고 있다고 주장합니다.
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
@Test
void add() throws Exception {
Foo foo = new Foo();
foo.add("One", "Two", "Three");
Assertions.assertThat(foo.getElements())
.containsExactly("One", "Two", "Three");
}
AssertJ의 좋은 점은 List
예상대로 선언하는 것이 불필요하다는 것입니다. 어설 션이 더 명확 하고 코드를 더 읽기 쉽게 만듭니다.
Assertions.assertThat(foo.getElements())
.containsExactly("One", "Two", "Three");
그러나 어설 션 / 매치 라이브러리는 반드시 더 필요하기 때문에 필수입니다.
이제 가정 Foo
하지 않습니다 상점 String
들하지만,이 Bar
인스턴스를이야.
그것은 매우 일반적인 요구입니다. AssertJ를 사용하면 어설 션을 쉽게 작성할 수 있습니다. equals()/hashCode()
JUnit 방식에 다음이 필요하지만 요소 클래스가 재정의되지 않더라도 목록 내용이 동일하다고 주장하는 것이 좋습니다 .
import org.assertj.core.api.Assertions;
import static org.assertj.core.groups.Tuple.tuple;
import org.junit.jupiter.api.Test;
@Test
void add() throws Exception {
Foo foo = new Foo();
foo.add(new Bar(1, "One"), new Bar(2, "Two"), new Bar(3, "Three"));
Assertions.assertThat(foo.getElements())
.extracting(Bar::getId, Bar::getName)
.containsExactly(tuple(1, "One"),
tuple(2, "Two"),
tuple(3, "Three"));
}
답변
요소의 순서에 신경 쓰지 않으면 ListAssert.assertEquals
junit-addons를 권장 합니다.
링크 : http://junit-addons.sourceforge.net/
게으른 Maven 사용자의 경우 :
<dependency>
<groupId>junit-addons</groupId>
<artifactId>junit-addons</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
답변
junit에서 assertEquals 를 사용할 수 있습니다 .
import org.junit.Assert;
import org.junit.Test;
@Test
public void test_array_pass()
{
List<String> actual = Arrays.asList("fee", "fi", "foe");
List<String> expected = Arrays.asList("fee", "fi", "foe");
Assert.assertEquals(actual,expected);
}
요소의 순서가 다르면 오류를 반환합니다.
모델 객체 목록을 주장하는 경우 특정 모델의 equals 메서드를 재정의해야합니다.
@Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj != null && obj instanceof ModelName) { ModelName other = (ModelName) obj; return this.getItem().equals(other.getItem()) ; } return false; }
답변
배열 목록을 작성하지 않으려는 경우에도 시도 할 수 있습니다
@Test
public void test_array_pass()
{
List<String> list = Arrays.asList("fee", "fi", "foe");
Strint listToString = list.toString();
Assert.assertTrue(listToString.contains("[fee, fi, foe]")); // passes
}