Cor*_*onA 7 java junit assertj
我有一个有效的 hamcrest 断言:
assertThat(mylist, contains(
containsString("15"),
containsString("217")));
Run Code Online (Sandbox Code Playgroud)
预期的行为是:
mylist == asList("Abcd15", "217aB") => 成功myList == asList("Abcd15", "218") => 失败如何将此表达式迁移到 assertJ。当然,存在一些幼稚的解决方案,例如断言第一个和第二个值,如下所示:
assertThat(mylist.get(0)).contains("15");
assertThat(mylist.get(1)).contains("217");
Run Code Online (Sandbox Code Playgroud)
但这些是对列表元素的断言,而不是对列表的断言。在列表上尝试断言将我限制为非常通用的函数。所以也许它只能通过自定义断言来解决,如下所示就可以了:
assertThat(mylist).elements()
.next().contains("15")
.next().contains("217")
Run Code Online (Sandbox Code Playgroud)
但是在我编写自定义断言之前,我会对其他人如何解决这个问题感兴趣?
编辑:一个额外的非功能性要求是,测试应该可以通过额外的约束轻松扩展。在 Hamcrest 中很容易表达额外的约束,例如
assertThat(mylist, contains(
emptyString(), //additional element
allOf(containsString("08"), containsString("15")), //extended constraint
containsString("217"))); // unchanged
Run Code Online (Sandbox Code Playgroud)
对于此示例,依赖于列表索引的测试必须重新编号,使用自定义条件的测试必须重写完整条件(请注意,中的约束allOf不限于子字符串检查)。
Syn*_*oli 14
satisfiesExactly.2021 年发布的 AssertJ v3.19.0 添加了一个satisfiesExactly方法。
所以你可以写:
\nassertThat(mylist)\n .satisfiesExactly(item1 -> assertThat(item1).contains("15"),\n item2 -> assertThat(item2).contains("217"));\nRun Code Online (Sandbox Code Playgroud)\n如果需要,您可以向各个元素添加更多断言:
\nassertThat(mylist)\n .satisfiesExactly(item1 -> assertThat(item1)\n .contains("08")\n .contains("15"),\n item2 -> assertThat(item2).contains("217"));\nRun Code Online (Sandbox Code Playgroud)\n与使用链的技术相比next(),该技术还为您检查列表大小。作为一个额外的好处,它允许您使用您喜欢的任何 lambda 参数,因此更容易阅读并跟踪您所在的元素。
对于这种断言,Hamcrest 优于 AssertJ,您可以使用条件模拟 Hamcrest,但您需要编写它们,因为 AssertJ 中没有提供开箱即用的功能(assertJ 的理念是不与 Hamcrest 在这方面竞争)。
在下一个 AssertJ 版本(即将发布!)中,您将能够重用 Hamcrest Matcher 来构建 AssertJ 条件,例如:
Condition<String> containing123 = new HamcrestCondition<>(containsString("123"));
// assertions succeed
assertThat("abc123").is(containing123);
assertThat("def456").isNot(containing123);
Run Code Online (Sandbox Code Playgroud)
最后一点,这个建议......
assertThat(mylist).elements()
.next().contains("15")
.next().contains("217")
Run Code Online (Sandbox Code Playgroud)
...不幸的是,由于泛型限制而无法工作,尽管您知道您有一个字符串列表,但 Java 泛型不够强大,无法StringAssert根据另一个 ( String)选择特定类型( ),这意味着您只能执行Object断言在元素上但不是String断言。
- 编辑 -
由于 3.13.0 可以asInstanceOf用来获取特定的类型断言,如果声明的类型是 Object 但运行时类型更具体,这很有用。
例子:
// Given a String declared as an Object
Object value = "Once upon a time in the west";
// With asInstanceOf, we switch to specific String assertion by specifying the InstanceOfAssertFactory for String
assertThat(value).asInstanceOf(InstanceOfAssertFactories.STRING)
.startsWith("Once");`
Run Code Online (Sandbox Code Playgroud)
见https://assertj.github.io/doc/#assertj-core-3.13.0-asInstanceOf
我发现的最接近的是编写一个“ContainsSubstring”条件,以及一个静态方法来创建一个条件,然后使用
assertThat(list).has(containsSubstring("15", atIndex(0)))
.has(containsSubstring("217", atIndex(1)));
Run Code Online (Sandbox Code Playgroud)
但也许你应该简单地写一个循环:
List<String> list = ...;
List<String> expectedSubstrings = Arrays.asList("15", "217");
for (int i = 0; i < list.size(); i++) {
assertThat(list.get(i)).contains(expectedSubstrings.get(i));
}
Run Code Online (Sandbox Code Playgroud)
或者编写一个参数化测试,以便 JUnit 本身在每个子字符串上测试每个元素。
| 归档时间: |
|
| 查看次数: |
17554 次 |
| 最近记录: |