Mateusz Chromiński
Mateusz Chromiński

Reputation: 2832

Testing all the elements in collection fulfil predicate

I need to test method which returns ordered List of some complex objects. Simplified example:

class MyObject {
    public String foo() { return someString; }
}

I want to test both: orderable of returned collection (since now I was using org.hamcrest.collection.IsIterableContainingInOrder.contains and fulfiling predicate).

To sum up. I'm looking for such syntax:

@Test
public void shouldMatchPredicate() {
    List<MyObject> collection = testObject.generate();
    //collection = [myObject#x, myObject#y, myObject#z]
    assertThat(collection, somePredicate("x", "y", "z")
}

Default one, contains method is not working, since first argument is Collection<MyObject> and arguments in predicate are Strings. I need some kind of bridge between it.

Upvotes: 1

Views: 3527

Answers (2)

John B
John B

Reputation: 32949

Since Predicate is a Guava object and Hamcrest does not depend on Guava it will not have a Matcher that will take a Predicate. Also, since Guava is not dependent on Hamcrest, they will not provide a Matcher either.

I suggest writing your own Matcher that takes a Predicate. This is relatively easy to do. Get the source code for IsIterableContainingInOrder and modify it to take a Predicate.

Another option would be to do the following:

assertThat(Iterables.all(myList, myPredicate), CoreMatchers.is(true));

This won't give you much documentation on a failure but it will pass/fail properly.

Upvotes: 2

Arialdo Martini
Arialdo Martini

Reputation: 4567

I would use a MyObjectFactory in testObject.generate(), avoiding the direct new statement. MyObjectFactory would be a dependency of testObject. Doing so, I would obtain 2 benefits:

  1. A weaker coupling between testObject and MyObject (testObject would know MyObject only in terms of interface
  2. The possibility to mock MyObjectFactory and, finally, the possibility to assert the 3 ordered calls: MyObjectFactory.BuildNewWithValue("x"), MyObjectFactory.BuildNewWithValue("y") and MyObjectFactory.BuildNewWithValue("z")

Your unit test would be an interaction test.

To assert the returned collection itself, I would write 3 asserts.

Upvotes: 1

Related Questions