简介:传说中的断言神器 AssertJ

AssertJ - Fluent assertions for java 简介。

官方文档 https://assertj.github.io/doc/

AssertJ提供了一套丰富而直观的强类型断言,用于单元测试(与JUnit、TestNG或任何其他测试框架一起使用)。
AssertJ provides a rich and intuitive set of strongly-typed assertions to use for unit testing (with JUnit, TestNG or any other test framework).

引入

1
2
3
4
5
6
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.18.1</version>
<scope>test</scope>
</dependency>

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// entry point for all assertThat methods and utility methods (e.g. entry)
import static org.assertj.core.api.Assertions.*;

// basic assertions
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);

// chaining string specific assertions
assertThat(frodo.getName()).startsWith("Fro")
.endsWith("do")
.isEqualToIgnoringCase("frodo");

// collection specific assertions (there are plenty more)
// in the examples below fellowshipOfTheRing is a List<TolkienCharacter>
assertThat(fellowshipOfTheRing).hasSize(9)
.contains(frodo, sam)
.doesNotContain(sauron);

// as() is used to describe the test and will be shown before the error message
assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);

// exception assertion, standard style ...
assertThatThrownBy(() -> { throw new Exception("boom!"); }).hasMessage("boom!");
// ... or BDD style
Throwable thrown = catchThrowable(() -> { throw new Exception("boom!"); });
assertThat(thrown).hasMessageContaining("boom");

// using the 'extracting' feature to check fellowshipOfTheRing character's names
assertThat(fellowshipOfTheRing).extracting(TolkienCharacter::getName)
.doesNotContain("Sauron", "Elrond");

// extracting multiple values at once grouped in tuples
assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name")
.contains(tuple("Boromir", 37, "Man"),
tuple("Sam", 38, "Hobbit"),
tuple("Legolas", 1000, "Elf"));

// filtering a collection before asserting
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
.containsOnly(aragorn, frodo, legolas, boromir);

// combining filtering and extraction (yes we can)
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
.containsOnly(aragorn, frodo, legolas, boromir)
.extracting(character -> character.getRace().getName())
.contains("Hobbit", "Elf", "Man");

// and many more assertions: iterable, stream, array, map, dates, path, file, numbers, predicate, optional ...

SoftAssertions

如果运行到折行断言失败,即使该用例,后面还有其他代码行,也不会继续执行下去。有时候我们不希望这种情况出现,SoftAssert就很好地帮我们解决了这个问题。

SoftAssert的特点

  1. 如果一个断言失败,会继续执行这个断言下的其他语句或者断言。
  2. 也就是一个用例有多个断言,失败了其中一个,不影响其他断言的运行
  3. 不要忘记调用assertAll()在该用例的最后一个断言后面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Test
public void verifiesScoreSoftly() {
Score score = Score.scoreBuilder()
.withValue(11)
.withCombination(dice(1, 1, 3, 4))
.withReminder(dice(6))
.build();

SoftAssertions softAssertions = new SoftAssertions();

softAssertions.assertThat(score.getValue())
.as("Has score")
.isEqualTo(8);
softAssertions.assertThat(score.getCombination())
.as("Has combination")
.isEqualTo(dice(1, 1, 3, 3));
softAssertions.assertThat(score.getReminder())
.as("Has reminder")
.isEqualTo(dice(5));

softAssertions.assertAll();
}

可以验证到所有断言失败:

1
2
3
4
5
org.assertj.core.api.SoftAssertionError: 
The following 3 assertions failed:
1) [Has score] expected:<[8]> but was:<[11]>
2) [Has combination] expected:<...alue=3}, Dice{value=[3]}]> but was:<...alue=3}, Dice{value=[4]}]>
3) [Has reminder] expected:<[Dice{value=[5]}]> but was:<[Dice{value=[6]}]>

JUnitSoftAssertions
代替手动创建SoftAssertions并调用其assertAll()我们可以使用JUnit @Rule :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Rule
public JUnitSoftAssertions softAssertions = new JUnitSoftAssertions();

@Test
public void verifiesScoreSoftlyUsingRule() {
Score score = Score.scoreBuilder()
.withValue(11)
.withCombination(dice(1, 1, 3, 4))
.withReminder(dice(6))
.build();

softAssertions.assertThat(score.getValue())
.as("Has score")
.isEqualTo(8);
softAssertions.assertThat(score.getCombination())
.as("Has combination")
.isEqualTo(dice(1, 1, 3, 3));
softAssertions.assertThat(score.getReminder())
.as("Has reminder")
.isEqualTo(dice(5));
}

(示例来源:https://blog.csdn.net/dnc8371/article/details/107264139)