custom Matcher's describeMismatchSafely not called in case of assert fails

893 views
Skip to first unread message

Marcel Overdijk

unread,
Feb 29, 2012, 8:29:59 AM2/29/12
to hamcre...@googlegroups.com
I have the following custom Matcher:

package nl.kapsalonreflection.app.test.response.matchers;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.jboss.resteasy.mock.MockHttpResponse;

public class HasStatusCode extends TypeSafeMatcher<MockHttpResponse> {

private Matcher<Integer> statusCodeMatcher;

public HasStatusCode(Matcher<Integer> statusMatcher) {
this.statusCodeMatcher = statusMatcher;
}

@Override
public boolean matchesSafely(MockHttpResponse item) {
return statusCodeMatcher.matches(item.getStatus());
}

@Override
public void describeTo(Description description) {
description.appendText("a response with status code ").appendDescriptionOf(statusCodeMatcher);
}

@Override
protected void describeMismatchSafely(MockHttpResponse item, Description mismatchDescription) {
System.out.println("has status code error... TODO: " + item.getStatus());
mismatchDescription.appendText("has status code error... TODO: " + item.getStatus());
}
}


which is invoked via a 

public static TypeSafeMatcher<MockHttpResponse> hasStatusCode(int statusCode) {
return hasStatusCode(is(statusCode));
}

like this: 

assertThat(response, hasStatusCode(200));


The matcher works. IT succeeds when status code is 200 and otherwise it fails.

However when it fails I expected it to print something like:

has status code error... TODO: 400

as being defined in describeMismatchSafely(..)

But this is not happening. The describeMismatchSafely is not even called in case of assertion failure.
Instead something like this is printed:

java.lang.AssertionError: 
Expected: a response with status code is <200>
     got: <org.jboss.resteasy.mock.MockHttpResponse@4824de7d>

at org.junit.Assert.assertThat(Assert.java:780)
at org.junit.Assert.assertThat(Assert.java:738)
at integration.resources.TestResourceIT.testList(TestResourceIT.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


I'm wondering if I'm doing something wrong here...

Steve Freeman

unread,
Feb 29, 2012, 8:46:16 AM2/29/12
to hamcre...@googlegroups.com
It might be better to use the TypeSafeDiagnosingMatcher

S

Marcel Overdijk

unread,
Feb 29, 2012, 9:31:33 AM2/29/12
to hamcre...@googlegroups.com
Thanks Steve, but I still not get message to appear...

I changed the code:

public class HasStatusCode extends TypeSafeDiagnosingMatcher<MockHttpResponse> {

private Matcher<Integer> matcher;

public HasStatusCode(Matcher<Integer> matcher) {
this.matcher = matcher;
}

@Override
public boolean matchesSafely(MockHttpResponse response, Description mismatchDescription) {
if (!matcher.matches(response.getStatus())) {
mismatchDescription.appendText("response status was " + response.getStatus());
mismatchDescription.appendDescriptionOf(matcher);
// matcher.describeMismatch(response.getStatus(), mismatchDescription);
return false;
}
return true;
}

@Override
public void describeTo(Description description) {
description.appendText("a response with status code ").appendDescriptionOf(matcher);
}
}

but I get the following output in Eclipse:

java.lang.AssertionError: 
Expected: a response with status code is <201>
     got: <org.jboss.resteasy.mock.MockHttpResponse@4585572a>

Steve Freeman

unread,
Feb 29, 2012, 10:10:14 AM2/29/12
to hamcre...@googlegroups.com
Are you actually passing it the same MockHttpResponse. Is it failing on the type matching?

Can you send use the relevant assertion line?

Also, are you using the JUnit.assertThat() ? It's out of date and doesn't write the mismatch. Make sure you're using MatcherAssert.assertThat()

S.

> --
> You received this message because you are subscribed to the Google Groups "Hamcrest Developers" group.
> To view this discussion on the web visit https://groups.google.com/d/msg/hamcrest-dev/-/k4RW7t2D1GsJ.
> To post to this group, send email to hamcre...@googlegroups.com.
> To unsubscribe from this group, send email to hamcrest-dev...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/hamcrest-dev?hl=en.

Steve Freeman

Winner of the Agile Alliance Gordon Pask award 2006
Book: http://www.growing-object-oriented-software.com

+44 797 179 4105
Twitter: @sf105
Higher Order Logic Limited
Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
Company registered in England & Wales. Number 7522677

Marcel Overdijk

unread,
Feb 29, 2012, 10:16:27 AM2/29/12
to hamcre...@googlegroups.com
I was indeed using JUnit.assertThat...

I fixed that to:
org.hamcrest.MatcherAssert.assertThat(response, hasStatusCode(201));

which now gives:

java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
at integration.resources.TestResourceIT.testList(TestResourceIT.java:57)
I'm using hamcrest 1.2.1

> To unsubscribe from this group, send email to hamcrest-dev+unsubscribe@googlegroups.com.


> For more options, visit this group at http://groups.google.com/group/hamcrest-dev?hl=en.

Steve Freeman

Winner of the Agile Alliance Gordon Pask award 2006
Book: http://www.growing-object-oriented-software.com

+44 797 179 4105
Twitter: @sf105
Higher Order Logic Limited
Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
Company registered in England & Wales. Number 7522677

> To unsubscribe from this group, send email to hamcrest-dev+unsubscribe@googlegroups.com.


> For more options, visit this group at http://groups.google.com/group/hamcrest-dev?hl=en.

Marcel Overdijk

unread,
Feb 29, 2012, 10:49:30 AM2/29/12
to hamcre...@googlegroups.com
I found out that I was using a junit jar including old hamcrest matcher. I switched to junit-dep and now it works.
Even the first posted example now works with the TypeSafeMatcher.

The first problem originated by using Junit.Assert...

Thanks for your help!

Steve Freeman

unread,
Feb 29, 2012, 10:49:44 AM2/29/12
to hamcre...@googlegroups.com
Sigh. Next thing is to use the junit-dep jar which, confusingly, does not include a hamcrest dependency.

S

>> hamcrest-dev...@googlegroups.com.

>> hamcrest-dev...@googlegroups.com.


>>> For more options, visit this group at
>> http://groups.google.com/group/hamcrest-dev?hl=en.
>>
>> Steve Freeman
>>
>> Winner of the Agile Alliance Gordon Pask award 2006
>> Book: http://www.growing-object-oriented-software.com
>>
>> +44 797 179 4105
>> Twitter: @sf105
>> Higher Order Logic Limited
>> Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
>> Company registered in England & Wales. Number 7522677
>>
>>
>

> --
> You received this message because you are subscribed to the Google Groups "Hamcrest Developers" group.

> To view this discussion on the web visit https://groups.google.com/d/msg/hamcrest-dev/-/wyJINX2aP1MJ.


> To post to this group, send email to hamcre...@googlegroups.com.

> To unsubscribe from this group, send email to hamcrest-dev...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages