How to claim that Iterable contains elements with a specific property?

Suppose I want a unit test method with this signature:

List<MyItem> getMyItems(); 

Suppose MyItem is a Pojo with many properties, one of which is "name" , accessed via getName() .

All I need to check is that List<MyItem> or any Iterable contains two instances of MyItem whose "name" properties have the values "foo" and "bar" . If any other properties do not match, I absolutely do not need the goals of this test. If the names match, this is a successful test.

I would like it to be single line, if possible. Here is some kind of "pseudo-syntax" of what I would like to do.

 assert(listEntriesMatchInAnyOrder(myClass.getMyItems(), property("name"), new String[]{"foo", "bar"}); 

Can Hamcrest be good for this kind of thing? If so, what exactly will be the hamcrest version of my pseudo-syntax above?

+96
java unit-testing junit4 hamcrest
Aug 28 2018-12-12T00:
source share
6 answers

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

import:

 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")) )); 
+113
Aug 28 '12 at 21:28
source share

Try:

 assertThat(myClass.getMyItems(), hasItem(hasProperty("YourProperty", is("YourValue")))); 
+49
Aug 28 '12 at 19:45
source share

This is not particularly a Hamcrest, but I think it is worth mentioning here. What I use quite often in Java8 looks something like this:

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

(Edited for a slight improvement by Rodrigo Magnari. This is a bit less detail. See comments.)

It may be a little harder to read, but I like the type and refactoring of security. It is also great for testing multiple bean properties in combination. for example with a java-like && expression in a lambda filter.

+39
Oct 19 '15 at 9:50
source share

Assertj is good at this.

 import static org.assertj.core.api.Assertions.assertThat; assertThat(myClass.getMyItems()).extracting("name").contains("foo", "bar"); 

A big plus for assertj compared to hamcrest is its simple use of code.

+19
Dec 22 '15 at 13:39 on
source share

AssertJ provides an excellent function in extracting() : you can pass Function to retrieve fields. It provides compile time validation.
You can also easily determine the size first.

This would give:

 import static org.assertj.core.api.Assertions; Assertions.assertThat(myClass.getMyItems()) .hasSize(2) .extracting(MyItem::getName) .containsExactlyInAnyOrder("foo", "bar"); 

containsExactlyInAnyOrder() states that the list contains only these values ​​in any order.

To claim that the list contains these values ​​in any order, but may contain other values, use contains() :

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



As a side note: to validate multiple fields from List items, using AssertJ we do this by putting the expected values ​​for each item in the tuple() function:

 import static org.assertj.core.api.Assertions; import static org.assertj.core.groups.Tuple; Assertions.assertThat(myClass.getMyItems()) .hasSize(2) .extracting(MyItem::getName, MyItem::getOtherValue) .containsExactlyInAnyOrder( tuple("foo", "OtherValueFoo"), tuple("bar", "OtherValueBar") ); 
+9
Aug 12 '18 at 19:33
source share

As long as your list is a concrete class, you can simply call the contains () method if you have implemented the equals () method in 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"))); 

It is assumed that you have implemented a constructor that accepts the values ​​that you want to assert. I understand that this is not one line, but it is useful to know what value is missing, and not to check both points.

+5
Aug 28 2018-12-12T00:
source share



All Articles