AssertJ使用教程(一)
介绍
Java测试中主要使用JUnit库进行测试,但是JUnit的断言相关API可读性不高,因此需要一款更好的断言库进行断言。AssertJ就是一款流式的断言库,大大提高了代码的可读性。
安装
Spring Boot
Spring Boot官方发行了一个Starter:spring-boot-starter-test,其中自带很多测试库,如JUnit,Mockito等,AssertJ也在这个Starter中。spring-boot-starter-test。
-
Gradle
testImplementation("org.springframework.boot:spring-boot-starter-test:2.7.3")
-
Maven
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>2.7.3</version> <scope>test</scope> </dependency>
Gradle
testImplementation("org.assertj:assertj-core:3.23.1")
Maven
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<!-- use 2.9.1 for Java 7 projects -->
<version>3.23.1</version>
<scope>test</scope>
</dependency>
在测试中引入AssertJ
AssertJ可以通过以下两种方式引入
-
使用import static导入测试方法
import static org.assertj.core.api.Assertions.*; // 或者使用下面的方法导入 // 最常用的测试方法 import static org.assertj.core.api.Assertions.assertThat; // 列表、字典、迭代器/Array import static org.assertj.core.api.Assertions.atIndex; import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.api.Assertions.filter; // 文件 import static org.assertj.core.api.Assertions.contentOf; // 其他不常用测试方法略 // 后续在测试方法中使用 assertThat("This is a string") .isNotNull() .startsWith("This") .contains("a") .endsWith("string");
-
实现WithAssertions接口
import org.assertj.core.api.WithAssertions; public class ExampleTest implements WithAssertions { @Test public void testAString() { assertThat("This is a string") .isNotNull() .startsWith("This") .contains("a") .endsWith("string"); } }
AssertJ常用的common assert
下面列举的assert方法在大部分情况下都可以使用。
辅助说明方法
这两类方法可以设置测试的信息以及失败后的提示信息.。要注意的是,这两个方法需要放在对应的测试前进行调用,否则不会生效!
-
as/describedAs
as(String description, Object ... args); // 对后续调用的测试进行描述 as(Supplier<String> descriptionSupplier); // 懒加载后续测试的描述,如果测试成功,那么Supplier不会被调用 describedAs(String description, Object ... args); // as方法的别名,因为'as'在Groovy中是关键字
-
overridingErrorMessage/withFailMessage
overridingErrorMessage(String newErrorMessage, Object... args); // 设置错误信息 overridingErrorMessage(Supplier<String> supplier); // 懒加载错误信息,如果测试成功,那么Supplier不会被调用 withFailMessage(String newErrorMessage, Object... args); // 设置错误信息 withFailMessage(Supplier<String> supplier); // 懒加载错误信息,效果同上
Equal/Null判断
用于判断一个对象是否是null,或者判断两个对象是否相等。
-
isEqualTo/isNotEqualTo
isEqualTo(Object expected); // 判断两个对象是否相等,使用equals方法 isNotEqualTo(Object other); // 与上面结果相反,使用equals方法
-
isNull/isNotNull
void isNull(); // 如果对象是null,那么测试通过且后续无法进行任何测试 isNotNull(); // 如果对象不是null,那么测试通过,后续可以继续进行测试
-
isSameAs/isNotSameAs(因为使用’==’进行判断,因此需要谨慎使用!)
isSameAs(Object expected); // 判断对象是否相等,使用'=='进行判断 isNotSameAs(Object other); // 与上面结果相反,使用'=='进行判断
类型判断
用于判断一个对象是否属于一个(或多个)类型,以及判断两个对象是否是同一类型。
-
isInstanceOf/isNotInstanceOf
isInstanceOf(Class<?> type); // 判断对象是否是type类型(相当于instanceof) isNotInstanceOf(Class<?> type); // 与isInstanceOf相反
-
isInstanceOfAny/isNotInstanceOfAny/isOfAnyClassIn/isNotOfAnyClassIn
isInstanceOfAny(Class<?>... types); // 如果对象类型是types中的任意一个,那么测试通过 isNotInstanceOfAny(Class<?>... types); // 与isInstanceOfAny相反 isOfAnyClassIn(Class<?>... types); // 同isInstanceOfAny isNotOfAnyClassIn(Class<?>... types); // 同isNotInstanceOfAny
-
isInstanceOfSatifying
isInstanceOfSatisfying(Class<T> type, Consumer<T> requirements); // 首先判断是否满足类型,之后判断是否满足后续的要求,举例如下 Consumer<String> requirements = string -> { assertThat(string).contains("substring").startsWith("beginning"); }; assertThat("beginning substring").isInstanceOfSatisfying(String.class, requirements);
-
isExactlyInstanceOf/isNotExactlyInstanceOf
isExactlyInstanceOf(Class<?> type); // 判断object.class是否等于type isNotExactlyInstanceOf(Class<?> type); // 与上面的结果相反,可能考虑子类的情况,举例如下 assertThat(new ArrayList<String>()).isExactlyInstanceOf(ArrayList.class); // 成功 assertThat(new ArrayList<String>()).isExactlyInstanceOf(List.class); // 失败
-
hasSameClassAs/doesNotHaveSameClassAs
hasSameClassAs(Object other); // 如果两个对象是相同类型,那么测试通过 doesNotHaveSameClassAs(Object other); // 与上面结果相反,举例如下 assertThat(new ArrayList<String>()).hasSameClassAs(new ArrayList<Integer>()); // 通过 assertThat(1).hasSameClassAs("abc"); // 不通过
ToString/HashCode判断
判断对象调用toString/hashCode方法后的结果
-
hasToString/doesNotHaveToString
hasToString(String expectedToString); // 如果对象在调用toString后的值与expectedToString一致,那么测试通过 doesNotHaveToString(String otherToString); // 与上面结果相反 // 以下两种方法是等效的 assertThat(object.toString()).isEqualTo(expected); assertThat(object).hasToString(expected);
-
hasSameHashCodeAs/doesNotHaveSameHashCodeAs
hasSameHashCodeAs(Object other); // 如果两个对象的Hash code一致,那么测试通过 doesNotHaveSameHashCodeAs(Object other); // 与上面结果相反 // 虽然这两个方法和上面的toString测试方法一样有等效方式,但是写起来比较麻烦,故在此省略
Matches方法
这个方法有两个重载,用于在AssertJ的API不方便进行判断是使用,需要传入一个Predicate类型的lambda表达式进行判断。
matches(Predicate<? super ACTUAL> predicate); // 传入Predicate进行测试
matches(Predicate<? super ACTUAL> predicate, String predicateDescription); // 传入Predicate及其描述信息
As方法
下面的方法用于进行简单的类型转换
-
asString
asString(); // 调用对象的toString方法,对后续toString的结果继续测试,举例如下 Object stringAsObject = "hello world"; assertThat(stringAsObject).asString().contains("hello");
-
asList
asList(); // 判断对象是不是List类型的对象,后续可以执行对List的测试方法,举例如下 Object sortedListAsObject = Arrays.asList(1, 2, 3); assertThat(sortedListAsObject).asList().isSorted();
-
asInstanceOf
// 因为代码有些复杂,因此贴出完整的类型定义 public <ASSERT extends AbstractAssert<?,?>> ASSERT asInstanceOf(InstanceOfAssertFactory<?,ASSERT> instanceOfAssertFactory); // 使用InstanceOfAssertFactory的对象来将对象转换成其他类型的对象(主要是Type Narrowing),以便对类型转换后的对象执行后续测试 // 举例如下 Object string = "abc"; assertThat(string).asInstanceOf(InstanceOfAssertFactories.STRING).startsWith("ab"); Object integer = 1; assertThat(integer).asInstanceOf(InstanceOfAssertFactories.INTEGER).isNotZero(); // 如果类型转换失败,测试会失败,举例如下 assertThat("abc").asInstanceOf(InstanceOfAssertFactories.INTEGER);