Junit의리스트에 대한 주장
JUnit 테스트 케이스 에서 목록에 대한 어설 션을 만드는 방법은 무엇입니까? 목록의 크기뿐만 아니라 목록의 내용도 포함됩니다.
나는 이것이 몇 년 전에 요청되었다는 것을 알고 있습니다. 아마도이 기능은 주변에 없었습니다. 그러나 지금은 이렇게하는 것이 쉽습니다.
@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>
배열 목록을 작성하지 않으려는 경우에도 시도 할 수 있습니다
@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
}
List<Integer> figureTypes = new ArrayList<Integer>(
Arrays.asList(
1,
2
));
List<Integer> figureTypes2 = new ArrayList<Integer>(
Arrays.asList(
1,
2));
assertTrue(figureTypes .equals(figureTypes2 ));
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);
}
요소의 순서가 다르면 오류를 반환합니다.
If you are asserting a model object list then you should override the equals method in the specific model.
@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; }
Don't reinvent the wheel!
There's a Google Code library that does this for you: Hamcrest
[Hamcrest] Provides a library of matcher objects (also known as constraints or predicates) allowing 'match' rules to be defined declaratively, to be used in other frameworks. Typical scenarios include testing frameworks, mocking libraries and UI validation rules.
I don't this the all the above answers are giving the exact solution for comparing two lists of Objects. Most of above approaches can be helpful in following limit of comparisons only - Size comparison - Reference comparison
But if we have same sized lists of objects and different data on the objects level then this comparison approaches won't help.
I think the following approach will work perfectly with overriding equals and hashcode method on the user-defined object.
I used Xstream lib for override equals and hashcode but we can override equals and hashcode by out won logics/comparison too.
Here is the example for your reference
import com.thoughtworks.xstream.XStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
class TestClass {
private String name;
private String id;
public void setName(String value) {
this.name = value;
}
public String getName() {
return this.name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
XStream xstream = new XStream();
String oxml = xstream.toXML(o);
String myxml = xstream.toXML(this);
return myxml.equals(oxml);
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
XStream xstream = new XStream();
String myxml = xstream.toXML(this);
return myxml.hashCode();
}
}
public class XstreamCompareTest {
public static void main(String[] args) throws ParseException {
checkObjectEquals();
}
private static void checkObjectEquals() {
List<TestClass> testList1 = new ArrayList<TestClass>();
TestClass tObj1 = new TestClass();
tObj1.setId("test3");
tObj1.setName("testname3");
testList1.add(tObj1);
TestClass tObj2 = new TestClass();
tObj2.setId("test2");
tObj2.setName("testname2");
testList1.add(tObj2);
testList1.sort((TestClass t1, TestClass t2) -> t1.getId().compareTo(t2.getId()));
List<TestClass> testList2 = new ArrayList<TestClass>();
TestClass tObj3 = new TestClass();
tObj3.setId("test3");
tObj3.setName("testname3");
testList2.add(tObj3);
TestClass tObj4 = new TestClass();
tObj4.setId("test2");
tObj4.setName("testname2");
testList2.add(tObj4);
testList2.sort((TestClass t1, TestClass t2) -> t1.getId().compareTo(t2.getId()));
if (isNotMatch(testList1, testList2)) {
System.out.println("The list are not matched");
} else {
System.out.println("The list are matched");
}
}
private static boolean isNotMatch(List<TestClass> clist1, List<TestClass> clist2) {
return clist1.size() != clist2.size() || !clist1.equals(clist2);
}
}
The most important thing is that you can ignore the fields by Annotation (@XStreamOmitField) if you don't want to include any fields on the equal check of Objects. There are many Annotations like this to configure so have a look deep about the annotations of this lib.
I am sure this answer will save your time to identify the correct approach for comparing two lists of objects :). Please comment if you see any issues on this.
참고URL : https://stackoverflow.com/questions/3236880/assert-about-a-list-in-junit
'development' 카테고리의 다른 글
Firebug에서 CSS 변경 사항을 저장할 수없는 이유는 무엇입니까? (0) | 2020.06.18 |
---|---|
URL이없는 상태간에 데이터를 전달하는 AngularJS UI 라우터 (0) | 2020.06.18 |
StringComparison.OrdinalIgnoreCase 또는 StringComparison.InvariantCultureIgnoreCase는 일반적으로 가장 적합한 방법은 무엇입니까? (0) | 2020.06.18 |
div 안에 내용 정렬 (0) | 2020.06.18 |
Python Argparse : 기본값 또는 지정된 값 (0) | 2020.06.18 |