说我有这样的课程:
public class Character {
public Character(String name){
this.name = name;
}
private String name;
public String getName() { return name; }
}
后来,一张地图
Map<Character, Integer> characterAges = new HashMap<Character, Integer>();
characterAges.put(new Character("Frodo"), 34);
使用assertj,测试该字符的最佳方法是什么?包括&#34; Frodo&#34;字符?对于这个年龄,我可以这样做:
assertThat(characterAges).hasValue(34);
我知道我能做到:
assertThat(characterAges.keySet())
.extracting("name")
.contains("Frodo");
但后来我失去了流利。我真正想要的是这样的事情:
assertThat(characterAges)
.hasKey(key.extracting("name").contains("Frodo")
.hasValue(34);
甚至更好,以便我可以确保我的密钥和值匹配:
assertThat(characterAges)
.hasEntry(key.extracting("name").contains("Frodo"), 34);
这样的事情可能吗?
答案 0 :(得分:5)
没有简单的解决方案。一种方法是为角色地图实现custom Assertion。以下是此问题的简单自定义断言示例:
public class CharacterMapAssert extends AbstractMapAssert<MapAssert<Character, Integer>, Map<Character, Integer>, Character, Integer> {
public CharacterMapAssert(Map<Character, Integer> actual) {
super(actual, CharacterMapAssert.class);
}
public static CharacterMapAssert assertThat(Map<Character, Integer> actual) {
return new CharacterMapAssert(actual);
}
public CharacterMapAssert hasNameWithAge(String name, int age) {
isNotNull();
for (Map.Entry<Character, Integer> entrySet : actual.entrySet()) {
if (entrySet.getKey().getName().contains(name) && (int) entrySet.getValue() == age) {
return this;
}
}
String msg = String.format("entry with name %s and age %s does not exist", name, age);
throw new AssertionError(msg);
}
}
在测试用例中:
assertThat(characterAges).hasNameWithAge("Frodo", 34);
请注意,您必须为每个自定义数据结构编写自己的断言。对于Character
类,您可以使用AssertJ assertions generator生成断言。
更新Java 8
使用Java 8也可以使用Lambda Expression
assertThat(characterAges).matches(
(Map<Character, Integer> t)
-> t.entrySet().stream().anyMatch((Map.Entry<Character, Integer> t1)
-> "Frodo".equals(t1.getKey().getName()) && 34 == t1.getValue()),
"is Frodo and 34 years old"
);
答案 1 :(得分:3)
您也可以这样做:
assertThat(characterAges).contains(entry("Frodo", 34), ...);
请参阅https://github.com/joel-costigliola/assertj-core/wiki/New-and-noteworthy#new-map-assertions
答案 2 :(得分:1)
AbstractMapAssert 的以下方法对您有用:
containsExactlyEntriesOf 验证实际地图是否只包含给定地图的条目,按顺序。这应该与 TreeMap 一起使用。 HashMap 不保证顺序,您的测试将随机失败。
containsExactlyInAnyOrderEntriesOf 验证实际地图是否只包含给定的条目,不包含其他任何顺序的条目。这将适用于 HashMap。
import java.util.Map;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
public class TestMapAssertions {
@Test
public void testCreateMap() {
//Call
Map<String, String> actual = ClassUnderTest.createMap();
//Assert
Assertions.assertThat(actual).containsExactlyInAnyOrderEntriesOf(
Map.of("Key1", "Value1", "Key2", "Value2")
);
}
public static class ClassUnderTest {
public static Map<String, String> createMap() {
return Map.of("Key1", "Value1", "Key2", "Value2");
}
}
}
答案 3 :(得分:0)
如果您不想遵循自定义断言路由,并且可以在测试中访问SUT(被测系统)中的字符实例,则另一个选择可能是
在SUT中:
Character frodo = new Character("Frodo");
characterAges.put(frodo, 34);
在测试中
MapEntry frodoAge34 = MapEntry.entry(frodo, 34);
assertThat(characterAges).contains(frodoAge34);
答案 4 :(得分:0)
我不确定介绍的日期/版本,但是MapAssert
中现在有很多断言。来自http://joel-costigliola.github.io/assertj/core-8/api/org/assertj/core/api/MapAssert.html:
包含(Map.Entry ...条目) -验证实际地图是否以任何顺序包含给定的条目。
containsAnyOf(Map.Entry ...条目) -验证实际地图是否至少包含给定条目之一。
containsExactly(Map.Entry ...条目) -确认实际地图按顺序仅包含给定的条目,而没有其他内容。
containsKeys(KEY ...键) -验证实际地图是否包含给定的键。
containsOnly(Map.Entry ...条目) -验证实际地图是否仅包含给定的条目,而没有任何其他顺序。
containsOnlyKeys(KEY ...键) -验证实际地图仅包含给定的键,而不包含任何顺序的任何其他内容。
containsValues(VALUE ...值) -验证实际地图是否包含给定的值。
doesNotContain(Map.Entry ...条目) -验证实际地图是否不包含给定的条目。
doesNotContainKeys(KEY ...键) -验证实际地图是否不包含任何给定键。
提取(Function,Object> ...提取器) -使用给定的功能将被测对象的值提取到一个列表中,该新列表成为被测对象。
例如,containsExactly()
应该可以解决问题。
答案 5 :(得分:0)
将.entrySet()
与.extracting()
一起使用怎么办?
assertThat(characterAges.entrySet())
.extracting(
entry -> entry.getKey().getName(),
Map.Entry::getValue)
.contains(tuple("Frodo", 34));
答案 6 :(得分:0)
从 3.6.0 开始,您可以使用 hasEntrySatisfying:
assertThat(characterAges)
.hasSize(1)
.hasEntrySatisfying(aKey, e ->
assertThat(e)
.isEqualTo(99.99)
);
在您的情况下,如果您不能使用密钥进行查找,您可以使用基于条件的 hasEntrySatisfying(更详细)。