What I've got is this line:
verify( mockAppendable ).append( org.mockito.Mockito.contains( msg ) );
... but I want this test to be case-indifferent. How would I do that?
What I've got is this line:
verify( mockAppendable ).append( org.mockito.Mockito.contains( msg ) );
... but I want this test to be case-indifferent. How would I do that?
On the page, what do they mean by "you can extract method" and is it possible to use a Java 8 lambda to make this a one-liner?
In a single line using case insensitivity code from here:
verify(mockAppendable)
.append(
argThat(arg ->
Pattern.compile(Pattern.quote(msg), Pattern.CASE_INSENSITIVE).matcher(arg).find()));
So they allowed the lambda version by skipping specifying a custom error message.
And by "you can extract a method", they mean:
verify(mockAppendable).append(argThat(containsCaseInsensitive(msg)));
And the method is defined as:
public static ArgumentMatcher<String> containsCaseInsensitive(final string s) {
if (s == null) throw new IllegalArgumentException("s is null");
final Pattern pattern = Pattern.compile(Pattern.quote(s), Pattern.CASE_INSENSITIVE);
return new ArgumentMatcher<String>() {
@Override
public boolean matches(String arg) {
return arg != null && pattern.matcher(arg).find();
}
@Override
public String toString() {
return String.format("[should have contained, ignoring case, \"%s\"]", s);
}
};
}
That's completely reusable, you can put that inside a new class like MocitoMatchers for example and call from many tests just like any of the built-in matchers.
Thanks to JB Nizet I've worked out that the answer appears to be a class like this:
class ContainsThisIgnoringCase implements ArgumentMatcher<String> {
private String msg;
ContainsThisIgnoringCase( String msg ){
this.msg = msg;
}
@Override
public boolean matches(String arg ) {
return arg.toLowerCase().contains( msg.toLowerCase() );
}
@Override
public String toString(){
return msg;
}
}
However, I'm puzzled by the stuff I then see on the page to which his link directs:
a) what do they mean by "you can extract method" and
b) is it possible to use a Java 8 lambda to make this a one-liner?
On the page, what do they mean by "you can extract method" and is it possible to use a Java 8 lambda to make this a one-liner?
This just means that instead of having to put new ListOfTwoElements()
in your test code, you could add a method to your test class called listOfTwoElements()
that returns a new ListOfTwoElements object to make the test code more fluent.
To answer your question about making this a one-liner, and more importantly, to answer this posting's original question, you can use MockitoHamcrest from the core Mockito library and IsEqualIgnoringCase from the Hamcrest library to get a one-liner without needing a custom class or lambda:
import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase;
import static org.mockito.Mockito.when;
import static org.mockito.hamcrest.MockitoHamcrest.argThat;
class CookieUtilTest {
@Mock
private HttpServletResponse response;
@Test
public void testHasCookiesDoesNotMatchCaseSensitiveCookieName() {
when(response.getHeaders(argThat(equalToIgnoringCase("Set-Cookie")))).thenReturn(singletonList("CookieNames=AreCaseSensitive"));
boolean testValue = CookieUtil.hasCookie("cookieNames", response);
verify(response).getHeaders(argThat(equalToIgnoringCase("Set-Cookie")));
assertThat(testValue).isFalse();
}
}
By far the easiest way without writing an extra matcher would be using the matches(String regex) helper. Just use the embedded case insensitive flag with your string and you are good to go:
verify( mockAppendable ).append( matches("(?i)the-message") );