[TOC]
https://github.com/joel-costigliola/assertj-core
https://github.com/joel-costigliola/assertj-examples
https://assertj.github.io/doc/
https://www.javadoc.io/doc/org.assertj/assertj-core/latest/org/assertj/core/api/Assertions.html
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<!-- use 2.9.1 for Java 7 projects -->
<version>3.15.0</version>
<scope>test</scope>
</dependency>
import static org.assertj.core.api.Assertions.*;
class DemoTest {
@Test
public void test(){
// 假设条件,满足则继续执行
assumeThat(frodo.getRace()).isNotEqualTo(ORC);
// 设置错误消息必须在调用断言之前完成
assertThat(frodo.getAge())
.as("check %s's age", frodo.getName())
.isNotNull().isNotZero().isGreaterThanOrEqualTo(80).isLessThan(200)
.isPositive().isNotNegative()
.isIn(Arrays.asList(100, 200));
// Output:
// [check Frodo's age] expected:<100> but was:<33>
// 必须在调用断言之前完成设置比较器的设置
assertThat(actual).usingComparator(new CustomComparator()).isEqualTo("a");
// 旧文档补充
assertThat(frodo).isNotEqualTo(sam);
assertThat(dateTime)
.isBefore("2004-12-13T21:39:45.618-08:00")
.isAfterYear(2013)
.isBetween("2018-01-01", "2018-08-31")
.isInSameHourAs(new Date())
.isToday();
}
}
import static org.assertj.core.api.Assertions.*;
class ExceptionTest {
/**
* BDD风格
* <br>行为驱动开发(Behavior-Driven Development)
* <br>是测试驱动开发(TDD)的延伸
* <br>GWT格式定义(GIVEN, WHEN, THEN)
*/
@Test
public void bdd_exception_assertion_example() {
// GIVEN
String[] names = { "Pier ", "Pol", "Jak" };
// WHEN
Throwable thrown = catchThrowable(() -> System.out.println(names[9]));
// THEN
assertThat(thrown).isInstanceOf(ArrayIndexOutOfBoundsException.class)
.hasMessageContaining("9");
// 检查消息
assertThat(thrown).hasMessage("foo is not a valid input");
assertThat(thrown).hasMessage("%s is not a valid input", "foo");
}
/** 检查类型 */
@Test
public void exception_assertion_example() {
assertThatThrownBy(() -> { throw new Exception("boom!"); })
.isInstanceOf(Exception.class)
.hasMessageContaining("boom");
/*
* assertThatNullPointerException
* assertThatIllegalArgumentException
* assertThatIllegalStateException
* assertThatIOException
*/
assertThatExceptionOfType(IOException.class)
.isThrownBy(() -> { throw new IOException("boom!"); })
.withMessage("%s!", "boom")
.withMessageContaining("boom")
.withNoCause();
// 无异常
assertThatCode(() -> {}).doesNotThrowAnyException();
}
@Test
public void java7_exception_assertion_example() {
try {
fellowshipOfTheRing.get(9); // argggl !
fail("IndexOutOfBoundsException expected because fellowshipOfTheRing has only 9 elements");
} catch (IndexOutOfBoundsException e) {
assertThat(e).hasMessage("Index: 9, Size: 9");
}
try {
fellowshipOfTheRing.get(9); // argggl !
// "Expected IndexOutOfBoundsException to be thrown"
failBecauseExceptionWasNotThrown(IndexOutOfBoundsException.class);
} catch (IndexOutOfBoundsException e) {
assertThat(e).hasMessage("Index: 9, Size: 9");
}
}
}
import static org.assertj.core.api.Assertions.*;
class FieldByFieldRecursiveComparisonTest {
@Test
public void test(){
Comparator<Double> closeEnough = (d1, d2) -> Math.abs(d1 - d2) <= 0.5 ? 0 : 1;
assertThat(sherlock).usingRecursiveComparison() // 只比较字段
.withStrictTypeChecking() // 同时比较类型(可以是子类形)
.ignoringFields("name", "home.address.street")
.ignoringFieldsMatchingRegexes(".*me")
.ignoringActualNullFields()
.ignoringFieldsOfTypes(double.class, Address.class)
.ignoringOverriddenEqualsForTypes(Address.class)
.withComparatorForFields(closeEnough, "height")
.isEqualTo(sherlockClone);
// 旧文档补充
assertThat(frodo).isEqualToComparingOnlyGivenFields(sam, "name", "race");
assertThat(jack).isEqualToComparingFieldByFieldRecursively(jackClone);
}
}
import static org.assertj.core.api.Assertions.*;
class SoftTest {
@Test
void basic_soft_assertions_example() {
// BDD爱好者可以使用BDD软断言,其中assertThat的替换为then
// BDDSoftAssertions softly = new BDDSoftAssertions();
SoftAssertions softly = new SoftAssertions();
softly.assertThat("George Martin").as("great authors").isEqualTo("JRR Tolkien");
softly.assertThat(42).as("response to Everything").isGreaterThan(100);
softly.assertThat("Gandalf").isEqualTo("Sauron");
// Don't forget to call assertAll() otherwise no assertion errors are reported!
softly.assertAll();
}
@Test
void auto_closeable_soft_assertions_example() {
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
softly.assertThat("George Martin").as("great authors").isEqualTo("JRR Tolkien");
softly.assertThat(42).as("response to Everything").isGreaterThan(100);
softly.assertThat("Gandalf").isEqualTo("Sauron");
// no need to call assertAll, this is done when softly is closed.
}
}
}
class SoftAutoTest {
@Rule
public final JUnitSoftAssertions softly = new JUnitSoftAssertions();
@Test
void junit4_soft_assertions_example() {
softly.assertThat("George Martin").as("great authors").isEqualTo("JRR Tolkien");
softly.assertThat(42).as("response to Everything").isGreaterThan(100);
softly.assertThat("Gandalf").isEqualTo("Sauron");
// No need to call softly.assertAll(), this is automatically done by the JUnitSoftAssertions rule
}
}
@ExtendWith(SoftAssertionsExtension.class)
public class JUnit5SoftAssertionsExample {
@Test
void junit5_soft_assertions_multiple_failures_example(SoftAssertions softly) {
softly.assertThat("George Martin").as("great authors").isEqualTo("JRR Tolkien");
softly.assertThat(42).as("response to Everything").isGreaterThan(100);
softly.assertThat("Gandalf").isEqualTo("Sauron");
// No need to call softly.assertAll(), this is automatically done by the SoftAssertionsExtension
}
}
http://joel-costigliola.github.io/assertj/assertj-core-conditions.html
// jedi is a Condition
assertThat("Yoda").is(jedi);
条件可以结合使用:
not(条件):不能满足给定条件
allOf(Condition ...):必须满足所有给定条件
anyOf(Condition ...):必须满足给定条件之一
您可以使用以下方法验证collection的元素上是否满足条件:
are(condition) / have(condition):所有元素必须满足给定条件
areAtLeast(n,condition) / haveAtLeast(n,condition):至少n个元素必须满足给定条件
areAtMost(n,condition) / haveAtMost(n,condition):满足给定条件的元素不超过n个
areExactly(n,condition) / haveExactly(n,condition):正好n个元素必须满足给定条件
此外,所有与Condition相关的方法都有其否定对应项,分别是is / isNot,have / doesNotHave,are / areNot,...
http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html
import org.assertj.core.api.Assertions;
import static org.assertj.core.api.Assertions.*;
class FeaturesTest {
@Test
public void test(){
// 是否读取私有字段,默认为true
Assertions.setAllowExtractingPrivateFields(false);
// 过滤
assertThat(fellowshipOfTheRing)
.filteredOn(character -> character.getName().contains("o"))
.filteredOn("race.name", not("Born")) // not,in,notIn
.containsOnly(aragorn, frodo, legolas, boromir);
// 提取字段
assertThat(fellowshipOfTheRing)
.extracting("name", "age", "race.name")
.contains(tuple("Boromir", 37, "Man"),
tuple("Sam", 38, "Hobbit"),
tuple("Legolas", 1000, "Elf"));
assertThat(greatHouses)
.extractingResultOf("sayTheWords")
.contains("Winter is Coming", "We Do Not Sow", "Hear Me Roar")
.doesNotContain("Lannisters always pay their debts");
// 文件断言
assertThat(xFile).exists().isFile().isRelative();
// 文件内容断言
assertThat(contentOf(xFile, "UTF-8"))
.startsWith("The Truth").contains("Is Out").endsWith("There");
}
}
http://joel-costigliola.github.io/assertj/assertj-db-concepts.html
https://www.javadoc.io/doc/org.assertj/assertj-db/latest/index.html
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-db</artifactId>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
import static org.assertj.core.api.Assertions.*;
class DbTest {
@Test
public void test(){
Source source = new Source("jdbc:h2:mem:test", "sa", "");
DataSource ds = new DataSourceWithLetterCase(dataSource,
tableLetterCase, columnLetterCase, pkLetterCase);
Source s = new SourceWithLetterCase("jdbc:h2:mem:test", "sa", "",
tableLetterCase, columnLetterCase, pkLetterCase);
Table table2 = new Table(source, "members");
// 仅包括
Table table3 = new Table(source, "members", new String[] { "id", "name" }, null);
// 排除
Table table4 = new Table(source, "members", null, new String[] { "birthdate" });
// 在包括中排除,即剩下 name
Table table5 = new Table(source, "members", new String[] { "id", "name" }, new String[] { "id" });
// language="SQL"
Request request4 = new Request(dataSource,
"select name, firstname from members " +
"where name like ? and firstname like ?;",
"%e%", "%Paul%");
assertThat(tableOrRequest).column().value(3).row(2).column(0).value();
// 下面两个是一样的,row, column, value 重复使用会到下一项
assertThat(table).column().value().returnToColumn().value();
assertThat(table).column().value().value();
}
}