I have written a custom Hamcrest Matcher<Double>
to use with Mockito.doubleThat
.
I want to "override the toString()
" method, so to speak, so that if there's a failure, the error is more verbose. Here's the JUnit failure trace:
Argument(s) are different! Wanted:
dependedOnComponent.method(
<Double matcher>
);
-> at my.domain.TestClass.testMethod(TestClass.java:123)
Actual invocation has different arguments:
dependedOnComponent.method(
123.45,
);
-> at my.domain.SystemUnderTest.callingMethod(SystemUnderTest.java:456)
As you can see, it prints <Double matcher>
. Is it possible to override that message? Instead, I would like to see, as an example:
Argument(s) are different! Wanted:
dependedOnComponent.method(
120 < matcher < 121
);
But a different instantiantion of my matcher class might be:
Argument(s) are different! Wanted:
dependedOnComponent.method(
1 < matcher < 200
);
I don't need to know how to write the code to generate the numbers or the syntax, I just need to know WHERE to put it.
So I was doing something silly; I was reading the Javadoc for Matcher when I really should have been looking at the Javadoc for ArgumentMatcher.
Once I realized my mistake, it's easy; just override the describeTo
method defined in that interface, e.g.
@Override
public void describeTo(Description description) {
description.appendText(String.valueOf(expected));
description.appendText(" ± ");
description.appendText(String.valueOf(delta));
}
Try the following:
@RunWith(MockitoJUnitRunner.class)
public class SOTest {
public interface Foo {
void doSomething(double d);
}
@Test
public void sillyTest() {
Foo foo = mock(Foo.class);
foo.doSomething(1);
verify(foo).doSomething(Mockito.doubleThat(new TestMatcher(2)));
}
public class TestMatcher extends CustomMatcher<Double> {
private final double expected;
public TestMatcher(double expected) {
super(Double.toString(expected));
this.expected = expected;
}
@Override
public boolean matches(Object item) {
return item instanceof Double && ((Double) item).equals(expected);
}
}
}
Output:
Argument(s) are different! Wanted:
foo.doSomething(2.0);
-> at SOTest.sillyTest(SOTest.java:23)
Actual invocation has different arguments:
foo.doSomething(1.0);
-> at SOTest.sillyTest(SOTest.java:22)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With