How do I assert an Iterable contains elements with a certain property?

橙三吉。 提交于 2019-11-27 00:45:37
Kevin Pauli

Thank you @Razvan who pointed me in the right direction. I was able to get it in one line and I successfully hunted down the imports for Hamcrest 1.3.

the imports:

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;

the code:

assertThat( myClass.getMyItems(), contains(
    hasProperty("name", is("foo")), 
    hasProperty("name", is("bar"))
));
Razvan

Try:

assertThat(myClass.getMyItems(),
                          hasItem(hasProperty("YourProperty", is("YourValue"))));

Its not especially Hamcrest, but I think it worth to mention here. What I use quite often in Java8 is something like:

assertTrue(myClass.getMyItems().stream().anyMatch(item -> "foo".equals(item.getName())));

(Edited to Rodrigo Manyari's slight improvement. It's a little less verbose. See comments.)

It may be a little bit harder to read, but I like the type and refactoring safety. Its also cool for testing multiple bean properties in combination. e.g. with a java-like && expression in the filter lambda.

Assertj is good at this.

import static org.assertj.core.api.Assertions.assertThat;

    assertThat(myClass.getMyItems()).extracting("name").contains("foo", "bar");

Big plus for assertj compared to hamcrest is easy use of code completion.

AssertJ provides an excellent feature in extracting() : you can pass Functions to extract fields. It provides a check at compile time.
You could also assert the size first easily.

It would give :

import static org.assertj.core.api.Assertions;

Assertions.assertThat(myClass.getMyItems())
          .hasSize(2)
          .extracting(MyItem::getName)
          .containsExactlyInAnyOrder("foo", "bar"); 

containsExactlyInAnyOrder() asserts that the list contains only these values whatever the order.

To assert that the list contains these values whatever the order but may also contain other values use contains() :

.contains("foo", "bar"); 

As long as your List is a concrete class, you can simply call the contains() method as long as you have implemented your equals() method on MyItem.

// 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")));

Assumes you have implemented a constructor that accepts the values you want to assert on. I realise this isn't on a single line, but it's useful to know which value is missing rather than checking both at once.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!