我真的很喜欢用Assertj宣传收藏。
通常,使用containsExactlyInAnyOrder
而不是主张单个元素(collection.get(0)
)更安全,更简单 - 即使只有一个元素,因为它可能会在将来发生变化。
挑战始于主张包含复杂对象的集合,因为将整个对象构造为预期元素可能很乏味。
要仅提取某些属性,我们可以使用.extracting(Foo::field1, Foo::field2)
。
var players = List.of(
new Player("Michael Jordan", new Team("Bulls")),
new Player("Kobe Bryant", new Team("Lakers")));
assertThat(players)
.extracting(Player::name, player -> player.team().name())
.containsExactly(
tuple("Michael Jordan", "Bulls"),
tuple("Kobe Bryant", "Lakers"));
但是,我倾向于将特性与字符串相连,因为我不喜欢与元组合作:
assertThat(players)
.extracting(player -> player.name() + " | " + player.team().name())
.containsExactly("Michael Jordan | Bulls",
"Kobe Bryant | Lakers");
原因是,默认情况下,Assertj在“实际”部分中提供了通用的“元组”表示。
复制时,必须手动适应Java代码,这可能不便。
例如:
Expecting actual:
[("Michael Jordan", "Bulls"),
("Kobe Bryant" "Lakers")]
我想要的是主张对象的“易于副本”表示:
Expecting actual:
[tuple("Michael Jordan", "Bulls"),
tuple("Kobe Bryant" "Lakers")]
幸运的是,有一种简单的方法可以通过3个简单的步骤进行全局修复。
- 定义自定义表示:
class CustomAssertJRepresentation extends StandardRepresentation {
static final CustomAssertJRepresentation INSTANCE = new CustomAssertJRepresentation();
@Override
protected String toStringOf(Tuple tuple) {
return "tuple" + super.toStringOf(tuple);
}
}
- 然后将其添加到全局配置中:
public class CustomAssertJConfiguration extends Configuration {
@Override
public Representation representation() {
return CustomAssertJRepresentation.INSTANCE;
}
@Override
public String describe() {
return "CustomAssertJConfiguration applied";
}
}
- 最后,在此文件中注册全局配置:
/src/test/resources/META-INF/services/org.assertj.core.configuration.Configuration
将包含:
my.package.CustomAssertJConfiguration
请参阅官方文档以获取更多信息:https://assertj.github.io/doc/#assertj-core-representation