首先,请注意IterableSubject.containsExactly()
断言输入,这意味着 “正好包含所提供的对象或失败”。 - 即使你可以在这里传递Matcher
对象 - 我们断言该列表恰好包含一个ExpectedType
实例。无论是现有的答案正确执行是不变的(而不是heenenee的方法,断言的ExpectedType
一个实例,任何数量的其他实例的,和你的解决方案断言列表包含的ExpectedType
实例的任何数量的)。当我读到你的问题时,你打算声明一个确切的属性,但不管这表明接受的解决方案存在问题 - 它可能会意外地导致你不打算做出的断言。
当我碰上这样的真理API的限制,第一件事我总是试图简单地分裂主张成单独的步骤。这通常证明书写容易,易于阅读,并且通常可以防止错误。可以理解的是,人们经常试图寻找优雅的单线队员,但一般来说,连续断言没有任何问题。
很难在这里击败策略:
assertThat(ls).hasSize(1);
assertThat(Iterables.getOnlyElement(ls)).isInstanceOf(String.class);
如果可迭代不是大小为1,我们会得到一个错误告诉我们,(随着迭代的内容)。如果是,我们断言唯一的元素是String
的一个实例。完成!
对于ň实例一般情况下,代码也不可否认变得有点混乱,但它仍然是合理的。我们只是用assertWithMessage()
包括有关在isInstanceOf()
断言名单的附加背景:
assertThat(ls).hasSize(n);
for (int i = 0; i < ls.size(); i++) {
assertWithMessage("list: %s - index: %s", ls, i)
.that(ls.get(i)).isInstanceOf(String.class);
}
这既是更具可读性和比实现自己的自定义Subject
更清楚正确的。
由于Truth 0.29你可以做的更好使用 “Fuzzy Truth” AKA Correspondence
。这允许您基本上描述集合的一些转换,然后断言该转换的结果。在这种情况下,我们将创建一个INSTANCEOF_CORRESPONDENCE
:
private static final Correspondence<Object, Class<?>> INSTANCEOF_CORRESPONDENCE =
new Correspondence<Object, Class<?>>() {
@Override
public boolean compare(@Nullable Object actual, @Nullable Class<?> expected) {
return expected.isInstance(actual);
}
@Override
public String toString() {
return "is instanceof";
}
};
现在你可以写一个漂亮的单行!
assertThat(ls).comparingElementsUsing(INSTANCEOF_CORRESPONDENCE)
.containsExactly(String.class);
这种方法在自定义对象的一大好处是它更可扩展的 - 如果你决定做一个不同的断言Correspondence
实现并不需要改变,只是你的断言:
assertThat(ls).comparingElementsUsing(INSTANCEOF_CORRESPONDENCE)
.doesNotContain(Integer.class);
也有tentative plans支持方法引用和lambda表达式与.comparingElementsUsing()
,这样你就可以写类似:
assertThat(ls).comparingElementsUsing((o, c) -> c.isInstance(o), "is instanceof")
.containsExactly(String.class);
的问题是真实的只要'IterableSubject'上的Truth'contains'动词检查元素的相等性。而“Matcher”不是'ExpectedType'。感谢您的回答(最终接受)。 – rds
请注意,您的'containsExactlyOneInstanceOf()'与['IterableSubject.containsExactly()'](https://google.github.io/truth/api/latest/com/google/common/truth/)行为不同IterableSubject.html#containsExactly-java.lang.Object ...-) - 真理的方法需要完全给定的对象,没有别的。 – dimo414