Showing posts with label hamcrest. Show all posts
Showing posts with label hamcrest. Show all posts

Friday, 8 January 2010

Ham and Chips

Rob Fletcher's blog post on gMock inspired me to try out hamcrest, but I was surprised to find out there's no simple way to match collections in mocked method arguments - the best I could come up with was this...
mock(tagLib).fieldLabel(instanceOf(Map), instanceOf(Closure)).returns("<label></label>")
which doesn't tell me whether I'm calling fieldLabel with the expected attributes. After a bit of searching I found the MapContentMatcher in the Spring Integration library, but didn't want include the whole jar just for that. It also had dependencies other libraries and was heavily typed with generics. Here's the cut down groovy version...
import org.hamcrest.*
import static org.hamcrest.core.AllOf.*
import org.hamcrest.Factory as HamcrestFactory

class MapContentMatcher extends TypeSafeDiagnosingMatcher<Map> {

Object key
Object value

MapContentMatcher(Object key, Object value) {
this.key = key
this.value = value
}

public boolean matchesSafely(Map actual, Description mismatchDescription) {
return actual.containsKey(key) && value == actual[key]
}

public void describeTo(Description description) {
description.appendText("$key:$value")
}

@HamcrestFactory
public static Matcher hasAllEntries(Map expected) {
return allOf(expected.collect { k, v ->
new MapContentMatcher(k, v)
})
}
}

Which can be used thus...
mock(tagLib).fieldLabel(hasAllEntries([id: expectedField, label:expectedHeading]), instanceOf(Closure)).returns("<label></label>")