/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockitousage.matchers;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.mockito.AdditionalMatchers;
import org.mockito.Mockito;
import org.mockito.StateMaster;
import org.mockito.exceptions.misusing.InvalidUseOfMatchersException;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockitousage.IMethods;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class)
public class InvalidUseOfMatchersTest {
private IMethods mock = Mockito.mock(IMethods.class);
@Test
public void should_detect_wrong_number_of_matchers_when_stubbing() {
when(mock.threeArgumentMethod(1, "2", "3")).thenReturn(null);
try {
when(mock.threeArgumentMethod(1, eq("2"), "3")).thenReturn(null);
fail();
} catch (InvalidUseOfMatchersException e) {
assertThat(e.getMessage())
.contains("3 matchers expected")
.contains("1 recorded");
}
}
@Test
public void should_detect_stupid_use_of_matchers_when_verifying() {
mock.oneArg(true);
eq("that's the stupid way");
eq("of using matchers");
try {
Mockito.verify(mock).oneArg(true);
fail();
} catch (InvalidUseOfMatchersException e) {
assertThat(e.getMessage())
.contains("Misplaced or misused argument matcher detected here");
e.printStackTrace();
}
}
@Test
public void should_not_scream_on_correct_usage() throws Exception {
mock.simpleMethod(AdditionalMatchers.not(eq("asd")));
mock.simpleMethod(AdditionalMatchers.or(eq("jkl"), eq("asd")));
}
@Test
public void should_scream_when_no_matchers_inside_not() {
try {
mock.simpleMethod(AdditionalMatchers.not("jkl"));
fail();
} catch (InvalidUseOfMatchersException e) {
assertThat(e.getMessage())
.contains("No matchers found for")
.containsIgnoringCase("Not(?)");
}
}
@Test
public void should_scream_when_not_enough_matchers_inside_or_AddtionalMatcher() {
try {
mock.simpleMethod(AdditionalMatchers.or(eq("jkl"), "asd"));
fail();
} catch (InvalidUseOfMatchersException e) {
assertThat(e.getMessage())
.containsIgnoringCase("inside additional matcher Or(?)")
.contains("2 sub matchers expected")
.contains("1 recorded");
}
}
@Test
public void should_scream_when_Matchers_count_dont_match_parameter_count() {
try {
mock.threeArgumentMethod(1, "asd", eq("asd"));
fail();
} catch (InvalidUseOfMatchersException e) {
assertThat(e.getMessage())
.contains("3 matchers expected")
.contains("1 recorded");
}
}
@Test
public void should_mention_matcher_when_misuse_detected() {
// Given
// When
Result run = new JUnitCore().run(ObjectMatcherMisuseOnPrimitiveSite.class);
// Then
assertThat(run.getFailures()).hasSize(2);
assertThat(run.getFailures().get(0).getException()).isInstanceOf(NullPointerException.class)
.hasMessage(null);
assertThat(run.getFailures().get(1).getException()).isInstanceOf(InvalidUseOfMatchersException.class)
.hasMessageContaining("primitive alternatives");
new StateMaster().reset();
}
@RunWith(MockitoJUnitRunner.class)
public static class ObjectMatcherMisuseOnPrimitiveSite {
@Test
public void fails_with_NPE() {
IMethods mock = Mockito.mock(IMethods.class);
doNothing().when(mock)
.twoArgumentMethod(eq(73),
(Integer) any()); // <= Raise NPE on this call site
}
}
}