我正在使用Hamcrest 1.3并试图以更紧凑的方式实现以下目标.
考虑以下测试用例:
@Test
public void testCase() throws Exception {
Collection<String> strings = Arrays.asList(
"string one",
"string two",
"string three"
);
// variant 1:
assertThat(strings, hasSize(greaterThan(2)));
assertThat(strings, hasItem(is("string two")));
// variant 2:
assertThat(strings, allOf(
hasSize(greaterThan(2)),
hasItem(is("string two"))
));
}
Run Code Online (Sandbox Code Playgroud)
这里的目标是检查集合的大小和要包含的一些特定项目.
在第一种变化是可能的并且被接受的情况下,这并不总是那么容易,因为集合本身可能是其他一些操作的结果,因此使用allOf
操作对其进行所有操作更有意义.这是在上面的第二个变体中完成的.
但是,包含第二个变体的代码将导致以下编译时错误:
error: no suitable method found for allOf(Matcher<Collection<? extends Object>>,Matcher<Iterable<? extends String>>)
Run Code Online (Sandbox Code Playgroud)
实际上是否有任何特定的方法来测试Hamcrest中使用单次操作(例如allOf
)的集合的大小和项目?
当我做一些编程练习时,我偶然发现了一个ClassCastException
.作为背景我正在提供演示的简化版本来演示问题:
给定一个只包含字符的字符串,
A
或者B
计算一个以字符为键的映射,并将出现的次数作为值.此外,地图应始终包含两个字符作为键(如果输入字符串中缺少字符,则值为零).
例子:
"A" => {A=1, B=0}
"AAB" => {A=2, B=1}
我的第一个解决方案如下:
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
public Map<Character, Long> createResult(String input) {
Map<Character, Long> map = input.chars()
.mapToObj(c -> (char) c)
.collect(groupingBy(c -> c, counting()));
map.putIfAbsent('A', 0L);
map.putIfAbsent('B', 0L);
return map;
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案有效,但我想尝试是否可以为groupingBy
函数提供默认值的地图:
public HashMap<Character, Long> createResult2(String input) {
return input.chars()
.mapToObj(c -> (char) c)
.collect(groupingBy(c -> c, this::mapFactory, counting()));
}
private HashMap<Character, Long> mapFactory() {
HashMap<Character, Long> map = …
Run Code Online (Sandbox Code Playgroud)