AssertJ
1、概述
AssertJ 是一个 Java 库,它提供了丰富的断言集和真正有用的错误消息,提高了测试代码的可读性。
AssertJ由几个模块组成:
- 核心模块:为 JDK 类型(String、Iterable、Stream、Path、File、Map,…)提供断言
- Guava模块:为 Guava 类型提供断言(Multimap、Optional,…)
- Joda Time模块:为Joda Time 类型(DateTime、LocalDateTime)提供断言
- Neo4J模块:为 Neo4J 类型(路径、节点、关系……)提供断言
- Swing模块:为Swing 用户界面的功能测试提供了简单直观的 API
不同的 AssertJ 主要版本取决于不同的 Java 版本:
- AssertJ 3.x 需要 Java 8 或更高版本
- AssertJ 2.x 需要 Java 7 或更高版本
- AssertJ 1.x 需要 Java 6 或更高版本
2、AssertJ 核心
AssertJ 核心提供 JDK 标准类型的断言,可以与 JUnit、TestNG 或任何其他测试框架一起使用。
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.4.1</version>
<scope>test</scope>
</dependency>
2.1、简单示例
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.assertj.core.api.Assertions.*;
public class DemoTest {
@Test
public void test() {
Person p1 = new Person("tom", 18);
Person p2 = new Person("jerry", 22);
//基础断言
assertThat(p1.getName()).isEqualTo("tom");
assertThat(p1).isNotEqualTo(p2);
//字符串断言
assertThat("hello")
.startsWith("he")
.endsWith("lo")
.isEqualToIgnoringCase("HELLO");
//集合断言
Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
assertThat(set).hasSize(3)
.contains("b", "c")
.doesNotContain("z");
//断言描述
assertThat(p1.getAge())
.as("check %d's age", p1.getAge())
.isEqualTo(18);
//异常断言,标准风格
assertThatThrownBy(() -> {
throw new Exception("boom!");
}).hasMessage("boom!");
//异常断言,BDD风格
Throwable thrown = catchThrowable(() -> {
throw new Exception("boom!");
});
assertThat(thrown).hasMessageContaining("boom");
//提取多个值为元组并断言
List<Person> list = new ArrayList<>();
list.add(p1);
list.add(p2);
assertThat(list).extracting("name", "age")
.contains(tuple("tom", 18), tuple("jerry", 22));
//断言之前过滤集合
assertThat(list).filteredOn(p -> p.getAge() > 18)
.containsOnly(p2);
//过滤和提取组合并断言
assertThat(list).filteredOn(p -> p.getAge() > 18)
.containsOnly(p2)
.extracting("name", "age")
.contains(tuple("jerry", 22));
}
class Person {
String name;
Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
}
2.2、断言入口
1)、Assertions
org.assertj.core.api.Assertions
是AssertJ断言所需的唯一类,它提供了所需的所有方法。
一个静态导入即可:
import static org.assertj.core.api.Assertions.*;
也可以细分后按需导入:
import static org.assertj.core.api.Assertions.assertThat; // main one
import static org.assertj.core.api.Assertions.atIndex; // for List assertions
import static org.assertj.core.api.Assertions.entry; // for Map assertions
import static org.assertj.core.api.Assertions.tuple; // when extracting several properties at once
import static org.assertj.core.api.Assertions.fail; // use when writing exception tests
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; // idem
import static org.assertj.core.api.Assertions.filter; // for Iterable/Array assertions
import static org.assertj.core.api.Assertions.offset; // for floating number assertions
import static org.assertj.core.api.Assertions.anyOf; // use with Condition
import static org.assertj.core.api.Assertions.contentOf; // use with File assertions
2)、WithAssertions
org.assertj.core.api.WithAssertions
接口是断言的另一个入口,只需实现该类即可。
import org.assertj.core.api.WithAssertions;
import org.junit.jupiter.api.Test;
public class WithAssertionsExamples implements WithAssertions {
@Test
public void test() {
//不需要静态导入,assertThat是来自于WithAssertions的方法
assertThat("hello").isEqualTo("hello");
assertThat(1).isInstanceOf(Number.class);
}
}
3)、BDDAssertions
org.assertj.core.api.BDDAssertions.then
是另一个断言入口。
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.BDDAssertions.then;
public class BDDAssertionsExamples {
@Test
public void test() {
//方法来自静态导入的BDDAssertions.then()
then("hello").isEqualTo("hello");
then(1).isInstanceOf(Number.class);
}
}
2.3、断言支持的类型
常见类型:
- BigDecimal
- BigInteger
- CharSequence
- Class
- Date
- File
- Future / CompletableFuture
- InputStream
- Iterable (including any kind of Collection)
- Iterator
- List
- Map
- Object
- Object[] and Object[][]
- Optional / OptionalInt / OptionalLong / OptionalDouble
- Path
- Predicate
- Stream
- String
- Throwable / Exception
原始类型:
- 原始类型及其包装器:
- short / Short
- int / Integer
- long / Long
- byte / Byte
- char / Character
- float / Float
- double / Double
- 原始类型数组:
- short[]
- int[]
- long[]
- byte[]
- char[]
- float[]
- double[]
- 原始类型二维数组:
- short[][]
- int[][]
- long[][]
- byte[][]
- char[][]
- float[][]
- double[][]
Java8时间类型:
- Instant
- LocalDate
- LocalDateTime
- LocalTime
- OffsetDateTime
- OffsetTime
- ZonedDateTime
- Period
原子类型:
- 原子基本类型:
- AtomicInteger
- AtomicLong
- AtomicBoolean
- 原子数组类型:
- AtomicIntegerArray
- AtomicLongArray
- 原子引用类型:
- AtomicMarkableReference
- AtomicStampedReferenceAssert
- 原子更新器类型:
- AtomicIntegerFieldUpdater
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater
- 加法器类型:
- LongAdder
2.4、断言描述
可以使用as
方法为断言添加描述。
@Test
public void asTest() {
//注意,要在断言之前调用as方法
assertThat("hello")
.as("描述")
.isEqualTo("hello");
assertThat(1)
.as("check %s num", 1)
.isGreaterThan(18);
}
java.lang.AssertionError: [check 1 num]
Expecting:
<1>
to be greater than:
<18>
AssertJ 可以打印每个断言描述(当设置时),为此调用Assertions.setPrintAssertionsDescription(true);
2.5、错误消息覆盖
可以使用如下两个方法覆盖默认的错误消息:
- overridingErrorMessage()
- withFailMessage()
@Test
public void errMessageTest() {
assertThat(1)
.withFailMessage("check %s num", 1)
.isGreaterThan(18);
assertThat(1)
.overridingErrorMessage("check %s num", 1)
.isGreaterThan(18);
}
如果构建错误消息的成本很高,请使用重载方法,采用 Supplier<String>
而不是String
,只有在断言失败时才会构建消息。
@Test
public void errMessageTest2() {
assertThat(1)
.withFailMessage(() -> "check num")
.isGreaterThan(18);
assertThat(1)
.overridingErrorMessage(() -> "check num")
.isGreaterThan(18);
}
2.6、配置AssertJ
有两种配置AssertJ的不同方法:
- 单独设置配置属性
- 全局设置配置属性
为了有效,必须在执行测试之前应用配置更改,这取决于测试的范围,这意味着不同的事情:
- 对于单个测试:更改测试中的配置并在@AfterEach方法中恢复它(JUnit 5)
- 对于类中的所有测试:更改方法中的配置@BeforeAll并恢复方法中的更改@AfterAll(JUnit 5)
- 要在任何测试之前更改配置可以使用以下选项:
- 编写 JUnit 5 扩展实现BeforeAllCallback.
- 注册您自己的Configuration子类并让 AssertJ自动发现它。
1)、配置单个属性
//是否允许使用私有字段进行比较
Assertions.setAllowComparingPrivateFields(true);
//是否允许提取私有字段
Assertions.setAllowExtractingPrivateFields(false);
//设置提取器是否考虑裸命名的属性方法
Assertions.setExtractBareNamePropertyMethods(false);
//是否使用宽松的日期解析
Assertions.setLenientDateParsing(true);
//为可迭代对象、数组和map设置在错误消息中显示的最大元素数
Assertions.setMaxElementsForPrinting(100);
//设置单行描述的最大长度
Assertions.setMaxLengthForSingleLineDescription(250);
//设置是否从断言错误堆栈跟踪中删除与 AssertJ 相关的元素
Assertions.setRemoveAssertJRelatedElementsFromStackTrace(true);
//注册一个Representation来控制 AssertJ 格式化断言错误消息中显示的不同类型的方式
//默认为StandardRepresentation
Assertions.useRepresentation(new StandardRepresentation());
//注册一些 AssertJ 将在日期断言中使用的自定义格式
Assertions.registerCustomDateFormat(new SimpleDateFormat());
//启用/禁用向控制台打印断言描述
Assertions.setPrintAssertionsDescription(true);
2)、Congifuration
从 3.13.0 开始,AssertJ 公开了一个org.assertj.core.configuration.Configuration
对象,提供对所有 AssertJ 全局可配置属性的访问。
//创建配置对象
Configuration configuration = new Configuration();
//设置属性
configuration.setBareNamePropertyExtraction(false);
configuration.setComparingPrivateFields(false);
configuration.setExtractingPrivateFields(false);
configuration.setLenientDateParsing(true);
configuration.setMaxElementsForPrinting(1001);
configuration.setMaxLengthForSingleLineDescription(81);
configuration.setRemoveAssertJRelatedElementsFromStackTrace(false);
//应用,不要忘记调用apply方法
configuration.applyAndDisplay();
2.7、常用断言
常用断言位于AbstractAssert类中:
- describedAs:设置之后将调用的断言的描述
- isEqualTo:验证实际值是否等于给定值,即使用equals比较
- isNotEqualTo:验证实际值是否不等于给定值,即使用equals比较
- isNull:验证是否为Null
- isNotNull:验证是否不为Null
- isSameAs:验证实际值是否与给定值相同,即使用==比较
- isNotSameAs:验证实际值是否与给定值不相同,即使用==比较
- isIn:验证实际值是否存在于给定的值数组/集合中
- isNotIn:验证实际值是否不存在于给定的值数组/集合中
- is/has/satisfies:验证实际值是否满足给定条件,has方法别名
- isNot/doesNotHave:验证实际值是否不满足给定条件。这个方法是doesNotHave的别名
- isInstanceOf:验证实际值是否是给定类型的实例
- isInstanceOfSatisfying:验证实际值是一个给定类型的实例,满足以Consumer表示的给定需求
- isInstanceOfAny:验证实际值是否为任何给定类型的实例
- isNotInstanceOf:验证实际值是否不是给定类型的实例
- isNotInstanceOfAny:验证实际值是否不为任何给定类型的实例
- hasSameClassAs:验证实际值是否与给定对象具有相同的类
- hasToString:验证toString方法的返回值是否一致
- doesNotHaveSameClassAs:验证实际值是否与给定对象不具有相同的类
- isExactlyInstanceOf:验证实际值是否恰好是给定类型的实例
- isNotExactlyInstanceOf:验证实际值是否恰好不是给定类型的实例
- isOfAnyClassIn:验证实际值类型是否在给定类型中
- isNotOfAnyClassIn:验证实际值类型是否不在给定类型中
- asList:验证实际值是List的一个实例,并返回一个列表断言,以允许在此调用中链接特定于列表的断言
- asString:为实际值的toString()返回一个String断言,以允许在此调用中链接特定于String的断言
- overridingErrorMessage:覆盖错误信息
- withFailMessage:覆盖错误信息
- usingComparator:使用给定的自定义比较器
- usingDefaultComparator:使用默认比较器
- matches:验证实际对象是否与给定谓词匹配
- satisfiesAnyOf:验证所测试的实际对象是否满足以Consumer表示的给定断言组中的至少一个
//设置断言描述
assertThat(1).describedAs("描述").isLessThan(2);
//equals比较
assertThat(Integer.valueOf(1)).isEqualTo(1);
assertThat(1).isNotEqualTo(2);
//是否为Null
String str = null;
assertThat(str).isNull();
assertThat(new Object()).isNotNull();
// ==比较引用
assertThat(Integer.valueOf(1)).isSameAs(Integer.valueOf(1));
assertThat(Integer.valueOf(128)).isNotSameAs(Integer.valueOf(128));
// 是否存在
List<Integer> list = Arrays.asList(4, 5, 6);
assertThat(1).isIn(1, 2, 3);
assertThat(4).isIn(list);
assertThat(9).isNotIn(1, 2, 3);
assertThat(9).isNotIn(list);
//条件断言
Condition<String> condition = new Condition<String>(s -> s.length() < 6, "a %s word", "short");
assertThat("hello").is(condition);
assertThat("hello").has(condition);
assertThat("hello").satisfies(condition);
//类型判断
assertThat(Integer.valueOf(1)).isInstanceOf(Number.class);
assertThat(Integer.valueOf(1)).isInstanceOfAny(Number.class, Integer.class);
assertThat(Integer.valueOf(1)).hasSameClassAs(Integer.valueOf(2));
2.8、对象断言
对象断言位于AbstractObjectAssert类中:
- as:添加描述
- hasNoNullFieldsOrProperties:断言实际对象没有空字段或属性(将继承的字段或属性考虑在内)
- hasAllNullFieldsOrProperties:断言实际对象只有空字段或属性
- hasNoNullFieldsOrPropertiesExcept:断言实际对象没有空字段或属性,除了给定的(继承的也要考虑在内)
- hasAllNullFieldsOrPropertiesExcept:断言实际对象只有空字段或属性,除了给定的(继承的也要考虑在内)
- usingComparatorForFields:允许设置一个特定的比较器来比较具有给定名称的属性或字段。一个典型的用法是比较给定精度的double/float字段
- usingComparatorForType:允许设置一个特定的比较器,将属性或字段与给定类型进行比较。典型的用法是在给定精度下比较数值类型的字段
- hasFieldOrProperty:断言实际对象是否具有指定的字段或属性
- hasFieldOrPropertyWithValue:断言实际对象具有给定值的指定字段或属性
- extracting:从被测对象中提取给定字段/属性的值到一个列表中,这个新列表成为被测对象
- returns:验证被测对象从给定的返回给定的期望值,一个典型的用法是传递一个方法引用来断言对象的属性
Book b1 = new Book();
//只有空字段
assertThat(b1).hasAllNullFieldsOrProperties();
b1.setName("三国演义");
assertThat(b1).hasAllNullFieldsOrPropertiesExcept("name");
//没有空字段
assertThat(b1).hasNoNullFieldsOrPropertiesExcept("author", "price");
b1.setAuthor("罗贯中");
b1.setPrice(22.22);
assertThat(b1).hasNoNullFieldsOrProperties();
//判断是否具有指定字段
assertThat(b1).hasFieldOrProperty("name");
assertThat(b1).hasFieldOrPropertyWithValue("name", "三国演义");
//提取值
assertThat(b1).extracting("name", "author")
.contains("三国演义", "罗贯中");
2.9、字符串断言
字符串断言位于AbstractCharSequenceAssert类中:
- isNullOrEmpty:验证字符串为Null或空
- isEmpty:验证字符串为空
- isNotEmpty:验证字符串非空
- isBlank:验证字符串为空或由一个或多个空格组成
- isNotBlank:验证字符串不为空或不由一个或多个空格组成
- containsWhitespaces:验证字符串包含一个或多个空格
- containsOnlyWhitespaces:验证字符串只包含空格
- doesNotContainAnyWhitespaces:验证字符串为Null、空或不包含任何空格
- doesNotContainOnlyWhitespaces:验证字符串至少有一个非空格字符
- hasSize:验证字符串具有指定长度
- hasSizeLessThan:验证字符串小于指定长度
- hasSizeLessThanOrEqualTo:验证字符串小于等于指定长度
- hasSizeGreaterThan:验证字符串大于指定长度
- hasSizeGreaterThanOrEqualTo:验证字符串大于等于指定长度
- hasSizeBetween:验证字符串具有给定边界(包含)之间的长度
- hasLineCount:验证字符串具有指定的行数
- hasSameSizeAs:验证实际字符串和给定字符串长度相同
- isEqualToIgnoringCase:忽略大小写比较相等
- isNotEqualToIgnoringCase:忽略大小写比较不相等
- containsOnlyDigits:验证字符串只包含数字
- containsOnlyOnce:验证字符串只包含一次给定序列
- contains:验证字符串包含指定子串
- containsSequence:验证字符串以指定顺序包含子串
- containsIgnoringCase:忽略大小写包含
- doesNotContain:验证字符串不包含子串
- doesNotContainIgnoringCase:验证字符串不包含子串(忽略大小写)
- doesNotContainPattern:验证字符串不包含给定的正则表达式
- startsWith:以…开头
- doesNotStartWith:不以…开头
- endsWith:以…结尾
- doesNotEndWith:不以…结尾
- matches:验证字符串与给定的正则表达式匹配
- doesNotMatch:验证字符串不与给定的正则表达式匹配
- isXmlEqualToContentOf:验证实际的字符串是否等于给定文件的内容
- isEqualToIgnoringWhitespace:验证实际的字符串等于给定的,忽略空格差异
- isNotEqualToIgnoringWhitespace:验证实际的字符串不等于给定的,忽略空格差异
- isEqualToNormalizingWhitespace:验证实际的字符串等于给定的,在两个字符串的空格被标准化之后
- isNotEqualToNormalizingWhitespace:验证实际的字符串不等于给定的,在两个字符串的空格被标准化之后
- isEqualToNormalizingPunctuationAndWhitespace:验证实际的字符串等于给定的,在两个字符串的标点符号被规范化之后
- isSubstringOf:验证实际的字符串是给定的子字符串(与contains相反的断言)
- containsPattern:验证实际的字符串是否包含给定的正则表达式
- isEqualToNormalizingNewlines:验证实际的字符串在规范化新行字符后等于另一个字符串
- isEqualToIgnoringNewLines:验证在两个字符串新行(\n, \r\n)被删除后,实际的字符串等于给定的字符串
- isLowerCase:验证是否全部为小写
- isUpperCase:验证是否全部为大写
//断言null、空、空格
assertThat("").isNullOrEmpty();
assertThat("").isEmpty();
assertThat("a").isNotEmpty();
assertThat(" ").isBlank();
assertThat("a").isNotBlank();
//包含空
assertThat("a b").containsWhitespaces();
assertThat(" ").containsOnlyWhitespaces();
assertThat("ab").doesNotContainAnyWhitespaces();
assertThat("a b c").doesNotContainOnlyWhitespaces();
//字符串长度
assertThat("hello").hasSize(5);
assertThat("hello").hasSizeLessThan(6);
assertThat("hello").hasSizeLessThanOrEqualTo(5);
assertThat("hello").hasSizeGreaterThan(4);
assertThat("hello").hasSizeLessThanOrEqualTo(5);
assertThat("hello").hasSizeBetween(4, 6);
assertThat("hello").hasSameSizeAs("world");
//字符串行数
assertThat("hello\nworld").hasLineCount(2);
//字符串相等
assertThat("hello").isEqualTo("hello");
assertThat("hello").isEqualToIgnoringCase("Hello");
assertThat("hello").isNotEqualToIgnoringCase("Hallo");
//忽略空格
assertThat("a b c").isEqualToIgnoringWhitespace("abc");
assertThat("a b c").isNotEqualToIgnoringWhitespace("aba");
//只包含数字
assertThat("1234").containsOnlyDigits();
//包含子串
assertThat("hello world").containsOnlyOnce("hel");
assertThat("hello world").contains("wor", "hel");
assertThat("hello world").containsSequence("hel", "lo");
assertThat("hello world").containsIgnoringCase("HEL");
assertThat("hello world").doesNotContain("bb");
assertThat("hello world").doesNotContainIgnoringCase("BB");
assertThat("hello world").doesNotContainPattern(Pattern.compile("^a.*"));
//开头结尾
assertThat("hello").startsWith("he");
assertThat("hello").doesNotStartWith("ha");
assertThat("hello").endsWith("lo");
assertThat("hello").doesNotEndWith("la");
//正则匹配
assertThat("hello").matches(Pattern.compile("^he.*"));
assertThat("hello").doesNotMatch(Pattern.compile("^ha.*"));
//子串
assertThat("abc").isSubstringOf("abcdef");
//大小写
assertThat("hello").isLowerCase();
assertThat("HELLO").isUpperCase();
2.10、可迭代断言
可迭代对象的断言都位于AbstractIterableAssert类中:
- isNullOrEmpty:Null或空
- isEmpty:验证为空
- isNotEmpty:非空
- hasSize:等于指定容量
- hasSizeGreaterThan:大于指定容量
- hasSizeGreaterThanOrEqualTo:大于等于指定容量
- hasSizeLessThan:小于指定容量
- hasSizeLessThanOrEqualTo:小于等于指定容量
- hasSizeBetween:在指定的范围之间
- hasSameSizeAs:与指定的可迭代对象有相同的容量
- contains:包含指定子元素
- containsOnly:只包含指定子元素,忽略顺序
- containsOnlyOnce:只包含给定值一次
- containsOnlyNulls:只包含null元素而不包含其他元素
- containsExactly:包含给定的值,而不包含其他值,此断言应仅用于具有一致迭代顺序的组(即不要与HashSet一起使用
- containsExactlyInAnyOrder:包含给定的值,且不包含其他值,忽略顺序
- containsExactlyInAnyOrderElementsOf:包含给定的值,且不包含其他值,忽略顺序
- isSubsetOf:存在指定的所有元素
- containsSequence:以正确的顺序包含指定值
- doesNotContainSequence:不以正确的顺序包含指定值
- containsSubsequence:验证实际组是否以正确的顺序包含给定的子序列(可能在它们之间有其他值
- doesNotContainSubsequence:验证实际的组不包含给定的子序列,子序列是由一组有序的值定义的,它们之间可能有额外的值
- doesNotContain:验证实际的组不包含给定的值
- doesNotContainAnyElementsOf:验证实际不包含给定Iterable的任何元素(即none)
- doesNotHaveDuplicates:不包含重复项
- startsWith:以…开始
- endsWith:以…结束
- containsNull:至少包含一个Null
- doesNotContainNull:不包含Null
- are:验证每个元素值满足给定条件
- areNot:验证每个元素值不满足给定条件
- have:验证所有元素满足给定条件
- doNotHave:验证所有元素不满足给定条件
- areAtLeastOne/haveAtLeastOne:至少存在一个满足条件的元素
- areAtLeast/haveAtLeast:至少有N个满足条件的元素
- areAtMost/haveAtMost:至多有N个满足条件的元素
- areExactly/haveExactly:恰好有N个满足条件的元素
- hasAtLeastOneElementOfType:至少有一个元素具有指定的类型
- hasOnlyElementsOfType:所有元素都具有指定的类型
- doesNotHaveAnyElementsOfTypes:所有元素不属于指定的类型(包括子类)
- hasOnlyElementsOfTypes:所有元素都是给定类型的实例
- containsAll:包含给定Iterable的所有元素,无论顺序
- containsAnyOf:至少包含给定值中的一个
- containsAnyElementsOf:至少包含一个给定的Iterable
- extracting:从Iterable的待测元素中提取给定字段或属性的值到一个新的Iterable中
- extractingResultOf:在被测试的Iterable的元素上提取给定方法调用的结果到一个新的Iterable中
- map:通过应用映射函数映射Iterable的test下的元素,结果列表成为test下的实例
- flatExtracting:通过应用函数提取Iterable元素的值,并将结果连接到一个列表中
- flatMap:通过应用给定的Function来映射被测试的Iterable元素,并将结果集合平展到列表中
- containsOnlyOnceElementsOf:和containsOnlyOnce效果一致
- filteredOn:过滤,保留指定
- filteredOnNull:过滤,保留指定或Null
- first:导航到第一个元素
- last:导航到最后一个元素
- element:导航到指定位置的元素
- allMatch:所有元素都匹配谓词
//null或空
assertThat(new ArrayList<>()).isNullOrEmpty();
assertThat(new ArrayList<>()).isEmpty();
assertThat(Arrays.asList(1, 2)).isNotEmpty();
//容量
assertThat(Arrays.asList(1, 2)).hasSize(2);
assertThat(Arrays.asList(1, 2)).hasSizeGreaterThan(1);
assertThat(Arrays.asList(1, 2)).hasSizeGreaterThanOrEqualTo(2);
assertThat(Arrays.asList(1, 2)).hasSizeLessThan(3);
assertThat(Arrays.asList(1, 2)).hasSizeLessThanOrEqualTo(2);
assertThat(Arrays.asList(1, 2)).hasSameSizeAs(Arrays.asList(3, 4));
//包含
assertThat(Arrays.asList(1, 2, 3, 4)).contains(2);
assertThat(Arrays.asList(1, 2, 3, 4)).containsOnly(2, 1, 3, 4);
assertThat(Arrays.asList(1, 2, 3, 4)).containsOnlyOnce(2);
assertThat(Arrays.asList(null, null)).containsOnlyNulls();
assertThat(Arrays.asList(1, 2, 3)).containsExactly(1, 2, 3);
assertThat(Arrays.asList(1, 2, 3)).containsExactlyInAnyOrder(2, 1, 3);
assertThat(Arrays.asList(1, 2, 3)).containsSequence(1, 2);
assertThat(Arrays.asList(1, 2, 3)).doesNotContainSequence(1, 3);
assertThat(Arrays.asList(1, 2, 3, null)).containsNull();
assertThat(Arrays.asList(1, 2, 3)).doesNotContainNull();
//开头结尾
assertThat(Arrays.asList(1, 2, 3)).startsWith(1);
assertThat(Arrays.asList(1, 2, 3)).endsWith(3);
//条件
assertThat(Arrays.asList(1, 2, 3)).are(new Condition<Integer>(num -> num > 0, "正数"));
assertThat(Arrays.asList(1, 2, 3)).have(new Condition<Integer>(num -> num > 0, "正数"));
//类型
assertThat(Arrays.asList(1, 2, 3)).hasAtLeastOneElementOfType(Integer.class);
assertThat(Arrays.asList(1, 2, 3)).hasOnlyElementsOfType(Integer.class);
assertThat(Arrays.asList(1, 2, 3)).doesNotHaveAnyElementsOfTypes(String.class);
assertThat(Arrays.asList(1, 2, 3)).hasOnlyElementsOfType(Integer.class);
//提取
Map<String, Integer> map = new HashMap<>();
map.put("one", 1);
map.put("two", 2);
map.put("three", 3);
assertThat(map).extracting("one", "two")
.contains(1, 2);
//过滤
assertThat(Arrays.asList(1, 3, 5, 7, 9)).filteredOn(e -> e > 5)
.contains(7, 9);
//导航
assertThat(Arrays.asList(1, 2, 3, 4)).first()
.isEqualTo(1);
assertThat(Arrays.asList(1, 2, 3, 4)).last()
.isEqualTo(4);
assertThat(Arrays.asList(1, 2, 3, 4)).element(2)
.isEqualTo(3);//下标从0开始
//谓词匹配
assertThat(Arrays.asList(1, 2, 3, 4)).allMatch(e -> e > 0);
2.11、数组断言
数组对象的断言都位于AbstractObjectArrayAssert类中:
- isNullOrEmpty
- isEmpty
- isNotEmpty
- hasSize
- hasSizeGreaterThan
- hasSizeGreaterThanOrEqualTo
- hasSizeLessThan
- hasSizeLessThanOrEqualTo
- hasSizeBetween
- hasSameSizeAs
- contains
- containsOnly
- containsOnlyOnce
- containsOnlyNulls
- containsExactly
- containsExactlyInAnyOrder
- containsExactlyInAnyOrderElementsOf
- isSubsetOf
- containsSequence
- doesNotContainSequence
- containsSubsequence
- doesNotContainSubsequence
- doesNotContain
- doesNotContainAnyElementsOf
- doesNotHaveDuplicates
- startsWith
- endsWith
- containsNull
- doesNotContainNull
- are
- areNot
- have
- doNotHave
- areAtLeastOne/haveAtLeastOne
- areAtLeast/haveAtLeast
- areAtMost/haveAtMost
- areExactly/haveExactly
- hasAtLeastOneElementOfType
- hasOnlyElementsOfType
- doesNotHaveAnyElementsOfTypes
- hasOnlyElementsOfTypes
- containsAll
- containsAnyOf
- containsAnyElementsOf
- extracting
- extractingResultOf
- map
- flatExtracting
- flatMap
- containsOnlyOnceElementsOf
- filteredOn
- filteredOnNull
- first
- last
- element
- allMatch
2.12、异常断言
异常断言位于AbstractThrowableAssert类中:
- hasMessage:验证实际Throwable的消息是否等于给定的消息
- hasCause:验证实际的Throwable具有与给定的原因相似的原因,即具有相同的类型和消息
- hasCauseReference:相同引用的Throwable
- hasNoCause:验证没有原因
- hasMessageStartingWith:验证实际Throwable的消息是否以给定的描述开始
- hasMessageContaining:验证实际Throwable的消息是否包含给定的描述
- hasMessageContainingAll:验证实际Throwable的消息是否包含给定的所有描述
- hasMessageNotContaining:验证实际Throwable的消息是否包含给定的描述
- hasMessageNotContainingAny:验证实际Throwable的消息至少包含一个给定的描述
- hasStackTraceContaining:验证实际Throwable的堆栈跟踪是否包含给定的描述
- hasMessageMatching:验证实际Throwable的消息是否与给定的正则表达式匹配
- hasMessageFindingMatch:验证实际Throwable的消息序列是否与给定的正则表达式匹配
- hasMessageEndingWith:验证实际Throwable的消息是否以给定的描述结束
- hasCauseInstanceOf:验证实际Throwable的原因是否是给定类型的实例
- hasCauseExactlyInstanceOf:验证实际Throwable的原因恰好是给定类型的实例
- hasRootCause:验证实际的Throwable具有与给定的类似的根源,即具有相同的类型和消息
- hasRootCauseInstanceOf:验证实际Throwable的根本原因是给定类型的实例
- hasRootCauseExactlyInstanceOf:验证实际Throwable的根本原因是恰好是给定类型的实例
- hasRootCauseMessage:验证实际Throwable的根本原因的消息是否等于给定的消息
- hasNoSuppressedExceptions:验证实际的Throwable没有抑制异常
- hasSuppressedException:验证实际的Throwable具有与给定的异常相似的抑制异常,即具有相同的类型和消息
- doesNotThrowAnyException:验证不抛出任何异常
//断言异常消息
Throwable throwable = new IllegalArgumentException("wrong amount 123");
assertThat(throwable).hasMessage("wrong amount 123")
.hasMessage("%s amount %d", "wrong", 123)
.hasMessageStartingWith("wrong")
.hasMessageStartingWith("%s a", "wrong")
.hasMessageContaining("wrong amount")
.hasMessageContainingAll("wrong", "amount")
.hasMessageEndingWith("123")
.hasMessageEndingWith("amount %s", "123")
.hasMessageMatching("wrong amount.*")
.hasMessageNotContaining("right")
.hasMessageNotContainingAny("right", "price");
//断言异常原因
NullPointerException cause = new NullPointerException("boom!");
Throwable t = new Throwable(cause);
assertThat(t).hasCause(cause)
.hasCauseInstanceOf(NullPointerException.class)
.hasCauseInstanceOf(RuntimeException.class)//可匹配父类
.hasCauseExactlyInstanceOf(NullPointerException.class);//严格匹配,只能相同类型
assertThatExceptionOfType(RuntimeException.class)
.isThrownBy(() -> {
throw new RuntimeException(new IllegalArgumentException("boom!"));
})
.havingCause()
.withMessage("boom!");
//断言异常根本原因
NullPointerException rootCause = new NullPointerException("null!");
Throwable err = new Throwable(new IllegalArgumentException(rootCause));
assertThat(err).hasRootCause(rootCause)
.hasRootCauseMessage("null!")
.hasRootCauseMessage("%s!", "null")
.hasRootCauseInstanceOf(NullPointerException.class)
.hasRootCauseInstanceOf(RuntimeException.class)
.hasRootCauseExactlyInstanceOf(NullPointerException.class);
assertThatExceptionOfType(RuntimeException.class)
.isThrownBy(() -> {
throw new RuntimeException(new IllegalArgumentException(new NullPointerException("root error")));
})
.havingRootCause()
.withMessage("root error");
//BDD风格
String[] names = {"Pier", "Pol", "Jak"};
Throwable thrown = catchThrowable(() -> {
//数组越界
System.out.println(names[9]);
});
then(thrown).isInstanceOf(ArrayIndexOutOfBoundsException.class)
.hasMessageContaining("9");
//断言抛出者
assertThatThrownBy(() -> {
throw new Exception("boom!");
}).isInstanceOf(Exception.class).hasMessageContaining("boom");
//断言异常类型
assertThatExceptionOfType(IOException.class)
.isThrownBy(() -> {
throw new IOException("boom!");
})
.withMessage("%s!", "boom")
.withMessageContaining("boom")
.withNoCause();
//断言没有异常
assertThatNoException().isThrownBy(() -> {
System.out.println("OK");
});
thenNoException().isThrownBy(() -> {
System.out.println("OK");
});
assertThatCode(() -> {
System.out.println( "OK");
}).doesNotThrowAnyException();
thenCode(() -> {
System.out.println("OK");
}).doesNotThrowAnyException();
2.13、逐字段递归比较
class Person {
String name;
double htight;
Home home = new Home();
public Person(String name, double htight) {
this.name = name;
this.htight = htight;
}
}
class Home {
Address address = new Address();
Date ownedSince;
}
static class Address {
int number;
String street;
}
@Test
public void test1() {
Person sherlock = new Person("Sherlock", 1.80);
sherlock.home.ownedSince = new Date(123);
sherlock.home.address.street = "Baker Street";
sherlock.home.address.number = 221;
Person sherlock2 = new Person("Sherlock", 1.80);
sherlock2.home.ownedSince = new Date(123);
sherlock2.home.address.street = "Baker Street";
sherlock2.home.address.number = 221;
//断言成功,逐字段递归比较
assertThat(sherlock).usingRecursiveComparison()
.isEqualTo(sherlock2);
//断言失败,因为Person只比较引用
assertThat(sherlock).isEqualTo(sherlock2);
}
可以在比较中忽略被测对象的字段,有几种方法可以指定要忽略的字段:
- ignoringFields(String… fieldsToIgnore)
- ignoringFieldsMatchingRegexes(String… regexes)
- ignoringFieldsOfTypes(Class… typesToIgnore)
- 嵌套字段可以这样指定:home.address.street
2.14、软断言
通过软断言,AssertJ 会收集所有断言错误,而不是在第一个错误处停止。由于软断言不会在第一个错误时失败,因此您需要告诉 AssertJ 何时报告捕获的断言错误,有不同的方法可以做到这一点:
- 调用assertAll()(基本方法)
- 使用JUnit 4 规则负责assertAll()每次测试后的调用
- 使用提供的JUnit 5 扩展注入一个SoftAssertions或一个参数并在每次测试后BDDSoftAssertions调用assertAll()
- 用一个AutoCloseableSoftAssertions
- 使用assertSoftly静态方法
//构建一个SoftAssertions实例来记录所有断言错误
SoftAssertions softly = new SoftAssertions();
//使用softly.assertThat而不是通常的assertThat方法
softly.assertThat("George Martin").as("great authors").isEqualTo("JRR Tolkien");
softly.assertThat(42).as("response to Everything").isGreaterThan(100);
softly.assertThat("Gandalf").isEqualTo("Sauron");
//不要忘记调用assertAll(),否则不会报告断言错误!
softly.assertAll();
2.15、假设
假设为条件测试执行提供支持,如果满足假设,则测试正常执行,如果不满足,则测试将中止并标记为忽略。
当继续执行给定的测试方法没有意义时,通常会使用假设 - 典型的用法是根据给定的操作系统/环境运行测试。
所有 AssertJ 假设都是Assumptions
类中的静态方法,它们与断言 API 匹配,但是名称assumeThat而不是assertThat.
//假设的条件
assumeThat("hello").isLowerCase();
//只有假设条件成立,才继续执行
assertThat(1).isLessThan(10);
3、Guava模块
AssertJ Guava 需要 Java 8 或更高版本。
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-guava</artifactId>
<version>3.25.1</version>
<scope>test</scope>
</dependency>
3.1、简单示例
该类org.assertj.guava.api.Assertions
是开始使用 AssertJ Guava 所需的唯一类。
import static org.assertj.guava.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.entry;
// Multimap assertions
Multimap<String, String> actual = ArrayListMultimap.create();
actual.putAll("Lakers", newArrayList("Kobe Bryant", "Magic Johnson", "Kareem Abdul Jabbar"));
actual.putAll("Spurs", newArrayList("Tony Parker", "Tim Duncan", "Manu Ginobili"));
assertThat(actual).containsKeys("Lakers", "Spurs");
assertThat(actual).contains(entry("Lakers", "Kobe Bryant"), entry("Spurs", "Tim Duncan"));
// Multiset assertions
Multiset<String> actual = HashMultiset.create();
actual.add("shoes", 2);
assertThat(actual).contains(2, "shoes");
assertThat(actual).containsAtLeast(1, "shoes");
assertThat(actual).containsAtMost(3, "shoes");
// Range assertions
Range<Integer> range = Range.closed(10, 12);
assertThat(range).isNotEmpty()
.contains(10, 11, 12)
.hasClosedLowerBound()
.hasLowerEndpointEqualTo(10)
.hasUpperEndpointEqualTo(12);
// Table assertions
Table<Integer, String, String> bestMovies = HashBasedTable.create();
bestMovies.put(1970, "Palme d'Or", "M.A.S.H");
bestMovies.put(1994, "Palme d'Or", "Pulp Fiction");
bestMovies.put(2008, "Palme d'Or", "Entre les murs");
bestMovies.put(2000, "Best picture Oscar", "American Beauty");
bestMovies.put(2011, "Goldener Bär", "A Separation");
assertThat(bestMovies).hasRowCount(5).hasColumnCount(3).hasSize(5)
.containsValues("American Beauty", "A Separation", "Pulp Fiction")
.containsCell(1994, "Palme d'Or", "Pulp Fiction")
.containsColumns("Palme d'Or", "Best picture Oscar", "Goldener Bär")
.containsRows(1970, 1994, 2000, 2008, 2011);
4、Joda Time模块
AssertJ Joda Time 主要版本取决于不同的 Java 版本:
- AssertJ Joda Time 2.x 需要 Java 8 或更高版本
- AssertJ Joda Time 1.x 需要 Java 7 或更高版本
<!-- 日期工具栏依赖 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-joda-time</artifactId>
<!-- use 1.1.0 for Java 7 projects -->
<version>2.2.0</version>
<scope>test</scope>
</dependency>
4.1、简单示例
该类org.assertj.jodatime.api.Assertions
是开始使用 AssertJ Joda Time 所需的唯一类。
import static org.assertj.jodatime.api.Assertions.assertThat;
DateTime dateTime1 = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeZone.UTC);
DateTime dateTime2 = new DateTime(2001, 1, 1, 0, 0, 0, DateTimeZone.UTC);
assertThat(dateTime1).isBefore(dateTime2);
assertThat(dateTime2).isAfterOrEqualTo(dateTime1);
//自动转换字符串
assertThat(new DateTime("2000-01-01")).isEqualTo("2000-01-01");
//datetime比较忽略秒和毫秒
dateTime1 = new DateTime(2000, 1, 1, 23, 50, 0, 0, DateTimeZone.UTC);
dateTime2 = new DateTime(2000, 1, 1, 23, 50, 10, 456, DateTimeZone.UTC);
assertThat(dateTime1).isEqualToIgnoringSeconds(dateTime2);
DateTime utcTime = new DateTime(2013, 6, 10, 0, 0, DateTimeZone.UTC);
DateTime cestTime = new DateTime(2013, 6, 10, 2, 0, DateTimeZone.forID("Europe/Berlin"));
assertThat(utcTime).as("in UTC time").isEqualTo(cestTime);
4.2、常用断言
1)、LocalDate
- hasYear(int expectedYear):验证实际年份LocalDate是否等于给定年份
- hasMonthOfYear(int expectedMonthOfYear):验证实际月份LocalDate是否等于给定月份
- hasDayOfMonth(int expectedDayOfMonth):验证实际的月份日期LocalDate是否等于给定的月份日期
- isAfter(org.joda.time.LocalDate other):
验证实际值是否LocalDate严格位于给定值之后 - isAfter(String localDateAsString):isAfter(DateTime)使用LocalDate给定构建的调用String必须遵循 ISO8601 格式yyyy-MM-dd
- isAfterOrEqualTo(org.joda.time.LocalDate other):验证实际值LocalDate是否晚于或等于给定值
- isAfterOrEqualTo(String localDateAsString):isAfterOrEqualTo(DateTime)使用LocalDate给定构建的调用String必须遵循 ISO8601 格式yyyy-MM-dd
- isBefore(org.joda.time.LocalDate other):验证实际值是否LocalDate严格位于给定值之前
- isBefore(String localDateAsString):isBefore(DateTime)使用LocalDate给定构建的调用String必须遵循 ISO8601 格式yyyy-MM-dd
- isBeforeOrEqualTo(org.joda.time.LocalDate other):验证实际值是否LocalDate早于或等于给定值
- isBeforeOrEqualTo(String localDateAsString):isBeforeOrEqualTo(DateTime)使用LocalDate给定构建的调用String必须遵循 ISO8601 格式yyyy-MM-dd
- isEqualTo(String localDateAsString):调用AbstractAssert.isEqualTo(Object)传递LocalDate给定的构建String,必须遵循 ISO8601 格式yyyy-MM-dd
- isIn(String… dateTimesAsString):isIn(DateTime…)使用从给定字符串构建的日期时间进行调用,该字符串必须遵循 ISO8601 格式yyyy-MM-dd
- isNotEqualTo(String localDateAsString):isNotEqualTo(DateTime)使用LocalDate给定构建的调用String必须遵循 ISO8601 格式yyyy-MM-dd
- isNotIn(String… localDatesAsString):isNotIn(org.joda.DateTime…)使用从给定字符串构建的 DateTime 进行调用,该字符串必须遵循 ISO8601 格式yyyy-MM-dd
assertThat(new LocalDate(2000, 1, 1))
.hasYear(2000)
.hasMonthOfYear(1)
.hasDayOfMonth(1);
LocalDate date1 = new LocalDate(2000, 1, 1);
LocalDate date2 = new LocalDate(2001, 1, 1);
assertThat(date1)
.isBefore(date2)
.isBeforeOrEqualTo(date2);
assertThat(date2)
.isAfter(date1)
.isAfterOrEqualTo(date1);
2)、LocalDateTime
- hasDayOfMonth(int expectedDayOfMonth):验证实际的月份日期LocalDateTime是否等于给定的月份日期
- hasHourOfDay(int expectedHourOfDay):验证实际小时数LocalDateTime是否等于给定小时数
- hasMillisOfSecond(int expectedMillisOfSecond):验证实际的毫秒数LocalDateTime是否等于给定的毫秒数
- hasMinuteOfHour(int expectedMinuteOfHour):验证实际分钟数是否LocalDateTime等于给定分钟数
- hasMonthOfYear(int expectedMonthOfYear):验证实际月份LocalDateTime是否等于给定月份
- hasSecondOfMinute(int expectedSecondOfMinute):验证实际秒数LocalDateTime是否等于给定秒数
- hasYear(int expectedYear):验证实际年份LocalDateTime是否等于给定年份
- isAfter(org.joda.time.LocalDateTime other):验证实际值是否LocalDateTime严格位于给定值之后
- isAfter(String localDateTimeAsString):
isAfter(DateTime)使用LocalDateTime给定构建的调用String必须遵循ISO DateTime 格式 - isAfterOrEqualTo(org.joda.time.LocalDateTime other):
验证实际值LocalDateTime是否晚于或等于给定值 - isAfterOrEqualTo(String localDateTimeAsString):isAfterOrEqualTo(DateTime)使用LocalDateTime给定构建的调用String必须遵循ISO DateTime 格式。
- isBefore(org.joda.time.LocalDateTime other):验证实际值是否LocalDateTime严格位于给定值之前
- isBefore(String localDateTimeAsString):isBefore(DateTime)使用LocalDateTime给定构建的调用String必须遵循ISO DateTime 格式。
- isBeforeOrEqualTo(org.joda.time.LocalDateTime other):验证实际值是否LocalDateTime早于或等于给定值
- isBeforeOrEqualTo(String localDateTimeAsString):
isBeforeOrEqualTo(DateTime)使用LocalDateTime给定构建的调用String必须遵循ISO DateTime 格式。 - isEqualTo(String localDateTimeAsString):
调用AbstractAssert.isEqualTo(Object)传递LocalDateTime从给定的构建String必须遵循ISO DateTime 格式。 - isEqualToIgnoringHours(org.joda.time.LocalDateTime other):
验证实际值和给定值是否LocalDateTime具有相同的年、月和日字段(比较时忽略小时、分钟、秒和毫秒字段) - isEqualToIgnoringMinutes(org.joda.time.LocalDateTime other):验证实际值和给定值是否LocalDateTime具有相同的年、月、日和小时字段(比较中忽略分、秒和毫秒字段)
- isEqualToIgnoringSeconds(org.joda.time.LocalDateTime other):验证实际值和给定值是否LocalDateTime具有相同的年、月、日、小时和分钟字段(相比之下,秒和毫秒字段被忽略)
- isEqualToIgnoringMillis(org.joda.time.LocalDateTime other):验证实际值和给定值是否LocalDateTime具有相同的年、月、日、小时、分钟和秒字段(比较时忽略毫秒字段)
- isIn(String… localDateTimesAsString):isIn(DateTime…)使用从给定字符串构建的日期时间进行调用,该字符串必须遵循ISO 日期时间格式
- isNotEqualTo(String localDateTimeAsString):
isNotEqualTo(DateTime)使用LocalDateTime给定构建的调用String必须遵循ISO 日期时间格式 - isNotIn(String… dateTimesAsString):isNotIn(org.joda.DateTime…)使用从给定字符串构建的 DateTime 进行调用,该字符串必须遵循ISO DateTime 格式
assertThat(new LocalDateTime(2000, 1, 1, 0, 0, 0))
.hasYear(2000)
.hasMonthOfYear(1)
.hasDayOfMonth(1)
.hasHourOfDay(0)
.hasMinuteOfHour(0)
.hasSecondOfMinute(0)
.hasMillisOfSecond(0);
LocalDateTime dateTime1 = new LocalDateTime(2000, 1, 1, 0,0, 0);
LocalDateTime dateTime2 = new LocalDateTime(2001, 1, 1, 0,0, 0);
assertThat(dateTime1)
.isBefore(dateTime2)
.isBeforeOrEqualTo(dateTime2);
assertThat(dateTime2)
.isAfter(dateTime1)
.isAfterOrEqualTo(dateTime1);
3)、DateTime
- hasDayOfMonth(int expectedDayOfMonth):验证实际的月份日期DateTime是否等于给定的月份日期
- hasHourOfDay(int expectedHourOfDay):验证实际小时数DateTime是否等于给定小时数
- hasMillisOfSecond(int expectedMillisOfSecond):验证实际的毫秒数DateTime是否等于给定的毫秒数
- hasMinuteOfHour(int expectedMinuteOfHour):验证实际分钟数是否DateTime等于给定分钟数
- hasMonthOfYear(int expectedMonthOfYear):验证实际月份DateTime是否等于给定月份
- hasSecondOfMinute(int expectedSecondOfMinute):验证实际秒数DateTime是否等于给定秒数
- hasYear(int expectedYear):
验证实际年份DateTime是否等于给定年份 - isAfter(org.joda.time.DateTime other):验证实际值是否DateTime严格位于给定值之后
- isAfter(String dateTimeAsString):
isAfter(DateTime)使用DateTime给定构建的调用String必须遵循ISO DateTime 格式。 - isAfterOrEqualTo(org.joda.time.DateTime other):
验证实际值DateTime是否晚于或等于给定值 - isAfterOrEqualTo(String dateTimeAsString):isAfterOrEqualTo(DateTime)使用DateTime给定构建的调用String必须遵循ISO DateTime 格式。
- isBefore(org.joda.time.DateTime other):验证实际值是否DateTime严格位于给定值之前
- isBefore(String dateTimeAsString):isBefore(DateTime)使用DateTime给定构建的调用String必须遵循ISO DateTime 格式。
- isBeforeOrEqualTo(org.joda.time.DateTime other):验证实际值是否DateTime早于或等于给定值
- isBeforeOrEqualTo(String dateTimeAsString):
isBeforeOrEqualTo(DateTime)使用DateTime给定构建的调用String必须遵循ISO DateTime 格式。 - isEqualTo(org.joda.time.DateTime expected):验证实际值是否DateTime等于实际值 DateTimeZone 中给定的值
- isEqualTo(String dateTimeAsString):isEqualTo(DateTime)使用DateTime给定构建的调用String必须遵循ISO DateTime 格式
- isEqualToIgnoringHours(org.joda.time.DateTime other):验证实际值和给定值是否DateTime具有相同的年、月和日字段(比较时忽略小时、分钟、秒和毫秒字段)
- isEqualToIgnoringMinutes(org.joda.time.DateTime other):验证实际值和给定值是否DateTime具有相同的年、月、日和小时字段(比较中忽略分、秒和毫秒字段)
- isEqualToIgnoringSeconds(org.joda.time.DateTime other):验证实际值和给定值是否DateTime具有相同的年、月、日、小时和分钟字段(相比之下,秒和毫秒字段被忽略)
- isEqualToIgnoringMillis(org.joda.time.DateTime other):验证实际值和给定值是否DateTime具有相同的年、月、日、小时、分钟和秒字段(比较时忽略毫秒字段)
- isIn(org.joda.time.DateTime… expected):
验证实际值DateTime是否等于DateTime实际值的 DateTimeZone 中给定的值之一
assertThat(new DateTime(2000, 1, 1, 0, 0, 0, 0))
.hasYear(2000)
.hasMonthOfYear(1)
.hasDayOfMonth(1)
.hasHourOfDay(0)
.hasMinuteOfHour(0)
.hasSecondOfMinute(0)
.hasMillisOfSecond(0);
DateTime dateTime1 = new DateTime(2000, 1, 1, 0,0, 0);
DateTime dateTime2 = new DateTime(2001, 1, 1, 0,0, 0);
assertThat(dateTime1)
.isBefore(dateTime2)
.isBeforeOrEqualTo(dateTime2);
assertThat(dateTime2)
.isAfter(dateTime1)
.isAfterOrEqualTo(dateTime1);
5、Neo4j模块
暂略…
6、DB模块
AssertJ-DB 提供断言来测试数据库中的数据。它需要 Java 8 或更高版本,并且可以与 JUnit 或 TestNG 一起使用。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-db</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
6.1、简单示例
该类org.assertj.db.api.Assertions.assertThat
是开始使用 AssertJ Joda Time 所需的唯一类。
假设数据库包含此MEMBERS表:
//创建mysql数据源
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setURL("jdbc:mysql:xxx:3306/demo");
dataSource.setUser("root");
dataSource.setPassword("123456");
//创建表
Table table = new Table(dataSource, "members");
//检查列
assertThat(table).column("name")
.value().isEqualTo("Hewson")
.value().isEqualTo("Evans")
.value().isEqualTo("Clayton")
.value().isEqualTo("Mullen");
//检查行
assertThat(table).row(1)
.value().isEqualTo(2)
.value().isEqualTo("Evans")
.value().isEqualTo("David Howell")
.value().isEqualTo("The Edge")
.value().isEqualTo(DateValue.of(2008, 8, 1))
.value().isEqualTo(1.77);