assertTrue()/ assertFalse():仅用于声明返回的布尔结果
assertTrue(Iterables.elementsEqual(argumentComponents,returnComponents)));
您要使用Assert.assertTrue()
或Assert.assertFalse()
作为被测方法返回一个boolean
值。
当方法返回特定的事物(如a)时List
,该事物应包含一些预期的元素,因此以assertTrue()
这种方式断言:Assert.assertTrue(myActualList.containsAll(myExpectedList)
是反模式。
它使断言易于编写,但是当测试失败时,也使调试变得困难,因为测试运行器只会对您说:
预期true
但实际是false
Assert.assertEquals(Object, Object)
在JUnit4或Assertions.assertIterableEquals(Iterable, Iterable)
JUnit 5中:仅用作两者,equals()
并且toString()
被比较对象的类(并深入)覆盖
这很重要,因为断言中的相等性测试依赖于equals()
并且测试失败消息依赖于toString()
比较对象。
由于String
覆盖了equals()
and toString()
,因此断言List<String>
with 是完全有效的assertEquals(Object,Object)
。关于此问题:您必须equals()
在类中进行重写,因为在对象相等性方面它是有意义的,不仅要使使用JUnit进行测试时的断言更容易。
为了使声明更容易,您可以采用其他方法(可以在答案的接下来的部分中看到)。
Guava是执行/构建单元测试断言的一种方法吗?
Google Guava Iterables.elementsEqual()是最好的方法,前提是我在构建路径中有库来比较这两个列表?
不它不是。Guava不是一个编写单元测试断言的库。
您不需要它来编写大多数(我认为)的单元测试。
比较单元测试列表的规范方法是什么?
作为一个好习惯,我赞成断言/匹配器库。
我不能鼓励JUnit执行特定的断言,因为它提供的功能实在太少且功能有限:它仅执行具有深等式的断言。
有时您希望允许元素中的任何顺序,有时您希望允许期望中的任何元素与实际元素匹配,因此...
因此,使用单元测试断言/匹配器库(例如Hamcrest或AssertJ)是正确的方法。
实际答案提供了Hamcrest解决方案。这是一个AssertJ解决方案。
org.assertj.core.api.ListAssert.containsExactly()
是您所需要的:它按顺序验证实际组中是否完全包含给定的值,而没有其他内容:
验证实际组是否按顺序完全包含给定的值,并且没有其他内容。
您的测试可能如下所示:
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
@Test
void ofComponent_AssertJ() throws Exception {
MyObject myObject = MyObject.ofComponents("One", "Two", "Three");
Assertions.assertThat(myObject.getComponents())
.containsExactly("One", "Two", "Three");
}
AssertJ的一个优点List
是不需要按预期声明a :它使断言更直接,代码更易读:
Assertions.assertThat(myObject.getComponents())
.containsExactly("One", "Two", "Three");
如果测试失败:
Assertions.assertThat(myObject.getComponents())
.containsExactly("One", "Two");
您会收到一条非常清晰的消息,例如:
java.lang.AssertionError:
期望:
<[“一个”,“两个”,“三个”]>
完全包含(并且顺序相同):
<[“一个”,“两个”]>
但是某些元素是无法预期的:
<[“三个”]>
断言/匹配器库是必须的,因为它们确实会进一步发展
假设其中MyObject
不存储,String
而是存储Foo
的实例,例如:
public class MyFooObject {
private List<Foo> values;
@SafeVarargs
public static MyFooObject ofComponents(Foo... values) {
}
public List<Foo> getComponents(){
return new ArrayList<>(values);
}
}
这是非常普遍的需求。使用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 ofComponent() throws Exception {
MyFooObject myObject = MyFooObject.ofComponents(new Foo(1, "One"), new Foo(2, "Two"), new Foo(3, "Three"));
Assertions.assertThat(myObject.getComponents())
.extracting(Foo::getId, Foo::getName)
.containsExactly(tuple(1, "One"),
tuple(2, "Two"),
tuple(3, "Three"));
}