Kev*_*uli 99 java unit-testing hamcrest junit4
假设我想使用此签名对方法进行单元测试:
List<MyItem> getMyItems();
Run Code Online (Sandbox Code Playgroud)
假设MyItem是一个Pojo,它有许多属性,其中一个是"name"通过访问的getName().
我关心验证的是List<MyItem>,或者任何Iterable,包含两个MyItem实例,其"name"属性具有值"foo"和"bar".如果任何其他属性不匹配,我真的不关心此测试的目的.如果名称匹配,则是成功的测试.
如果可能的话,我希望它是单行的.这是我想要做的事情的一些"伪语法".
assert(listEntriesMatchInAnyOrder(myClass.getMyItems(), property("name"), new String[]{"foo", "bar"});
Run Code Online (Sandbox Code Playgroud)
哈姆克雷斯特会对这类事情有好处吗?如果是这样,我上面的伪语法的hamcrest版本到底是什么?
Kev*_*uli 116
谢谢@Razvan,他指出了我正确的方向.我能够在一条线上获得它并且我成功地追捕了Hamcrest 1.3的进口.
进口:
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
Run Code Online (Sandbox Code Playgroud)
代码:
assertThat( myClass.getMyItems(), contains(
hasProperty("name", is("foo")),
hasProperty("name", is("bar"))
));
Run Code Online (Sandbox Code Playgroud)
Raz*_*van 49
尝试:
assertThat(myClass.getMyItems(),
hasItem(hasProperty("YourProperty", is("YourValue"))));
Run Code Online (Sandbox Code Playgroud)
Mar*_*Eis 40
它不是特别的Hamcrest,但我认为值得一提.我在Java8中经常使用的是:
assertTrue(myClass.getMyItems().stream().anyMatch(item -> "foo".equals(item.getName())));
Run Code Online (Sandbox Code Playgroud)
(编辑Rodrigo Manyari的轻微改进.它的冗长一点.请参阅评论.)
它可能有点难以阅读,但我喜欢类型和重构安全性.它对于组合测试多个bean属性也很酷.例如,在过滤器lambda中使用类似java的&&表达式.
Fra*_*ung 20
Assertj擅长这一点.
import static org.assertj.core.api.Assertions.assertThat;
assertThat(myClass.getMyItems()).extracting("name").contains("foo", "bar");
Run Code Online (Sandbox Code Playgroud)
与hamcrest相比,assertj的大优点是易于使用代码完成.
dav*_*xxx 10
AssertJ提供了一个很好的功能extracting():你可以传递Functions来提取字段.它在编译时提供检查.
您也可以轻松地断言尺寸.
它会给:
import static org.assertj.core.api.Assertions;
Assertions.assertThat(myClass.getMyItems())
.hasSize(2)
.extracting(MyItem::getName)
.containsExactlyInAnyOrder("foo", "bar");
Run Code Online (Sandbox Code Playgroud)
containsExactlyInAnyOrder() 断言该列表仅包含这些值,无论顺序如何.
要声明列表包含这些值,无论顺序如何,但也可能包含其他值,请使用contains():
.contains("foo", "bar");
Run Code Online (Sandbox Code Playgroud)
只要您的List是一个具体的类,只要在MyItem上实现了equals()方法,就可以简单地调用contains()方法。
// given
// some input ... you to complete
// when
List<MyItems> results = service.getMyItems();
// then
assertTrue(results.contains(new MyItem("foo")));
assertTrue(results.contains(new MyItem("bar")));
Run Code Online (Sandbox Code Playgroud)
假设您实现了一个构造函数,该构造函数接受要声明的值。我意识到这不是一行,但是知道丢失哪个值而不是一次检查两个值很有用。
AssertJ 3.9.1 支持在方法中直接使用谓词anyMatch。
assertThat(collection).anyMatch(element -> element.someProperty.satisfiesSomeCondition())
Run Code Online (Sandbox Code Playgroud)
这通常适合任意复杂条件的用例。
对于简单的条件,我更喜欢使用extracting方法(见上文),因为结果可迭代的测试可能支持具有更好可读性的值验证。例如:它可以提供专门的API,例如containsFrank Neblung答案中的方法。或者您可以anyMatch稍后调用它并使用方法引用,例如"searchedvalue"::equals. 也可以将多个提取器放入extracting方法中,随后使用 验证结果tuple()。
| 归档时间: |
|
| 查看次数: |
115067 次 |
| 最近记录: |