| package org.mockito.internal.invocation; |
| |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.mockito.internal.invocation.TypeSafeMatching.matchesTypeSafe; |
| |
| import java.util.Date; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.mockito.ArgumentMatcher; |
| import org.mockito.Mock; |
| import org.mockito.internal.matchers.LessOrEqual; |
| import org.mockito.internal.matchers.Null; |
| import org.mockito.internal.matchers.StartsWith; |
| import org.mockito.junit.MockitoJUnit; |
| import org.mockito.junit.MockitoRule; |
| import org.mockitousage.IMethods; |
| |
| public class TypeSafeMatchingTest { |
| |
| private static final Object NOT_A_COMPARABLE = new Object(); |
| |
| @Rule |
| public MockitoRule mockitoRule = MockitoJUnit.rule(); |
| |
| @Mock |
| public IMethods mock; |
| |
| /** |
| * Should not throw an {@link NullPointerException} |
| * |
| * @see Bug-ID https://github.com/mockito/mockito/issues/457 |
| */ |
| @Test |
| public void compareNullArgument() { |
| boolean match = matchesTypeSafe().apply(new LessOrEqual<Integer>(5), null); |
| assertThat(match).isFalse(); |
| |
| } |
| |
| /** |
| * Should not throw an {@link ClassCastException} |
| */ |
| @Test |
| public void compareToNonCompareable() { |
| boolean match = matchesTypeSafe().apply(new LessOrEqual<Integer>(5), NOT_A_COMPARABLE); |
| assertThat(match).isFalse(); |
| } |
| |
| /** |
| * Should not throw an {@link ClassCastException} |
| */ |
| @Test |
| public void compareToNull() { |
| boolean match = matchesTypeSafe().apply(new LessOrEqual<Integer>(null), null); |
| assertThat(match).isFalse(); |
| } |
| |
| /** |
| * Should not throw an {@link ClassCastException} |
| */ |
| @Test |
| public void compareToNull2() { |
| boolean match = matchesTypeSafe().apply(Null.NULL, null); |
| assertThat(match).isTrue(); |
| } |
| |
| /** |
| * Should not throw an {@link ClassCastException} |
| */ |
| @Test |
| public void compareToStringVsInt() { |
| boolean match = matchesTypeSafe().apply(new StartsWith("Hello"), 123); |
| assertThat(match).isFalse(); |
| } |
| |
| @Test |
| public void compareToIntVsString() throws Exception { |
| boolean match = matchesTypeSafe().apply(new LessOrEqual<Integer>(5), "Hello"); |
| assertThat(match).isFalse(); |
| } |
| |
| @Test |
| public void matchesOverloadsMustBeIgnored() { |
| class TestMatcher implements ArgumentMatcher<Integer> { |
| @Override |
| public boolean matches(Integer arg) { |
| return false; |
| } |
| |
| @SuppressWarnings("unused") |
| public boolean matches(Date arg) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @SuppressWarnings("unused") |
| public boolean matches(Integer arg, Void v) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| } |
| |
| boolean match = matchesTypeSafe().apply(new TestMatcher(), 123); |
| assertThat(match).isFalse(); |
| } |
| |
| @Test |
| public void matchesWithSubTypeExtendingGenericClass() { |
| abstract class GenericMatcher<T> implements ArgumentMatcher<T> { |
| } |
| class TestMatcher extends GenericMatcher<Integer> { |
| @Override |
| public boolean matches(Integer argument) { |
| return true; |
| } |
| } |
| boolean match = matchesTypeSafe().apply(new TestMatcher(), 123); |
| assertThat(match).isTrue(); |
| } |
| |
| @Test |
| public void dontMatchesWithSubTypeExtendingGenericClass() { |
| final AtomicBoolean wasCalled = new AtomicBoolean(); |
| |
| abstract class GenericMatcher<T> implements ArgumentMatcher<T> { |
| } |
| class TestMatcher extends GenericMatcher<Integer> { |
| @Override |
| public boolean matches(Integer argument) { |
| wasCalled.set(true); |
| return true; |
| } |
| } |
| wasCalled.set(false); |
| matchesTypeSafe().apply(new TestMatcher(), 123); |
| assertThat(wasCalled.get()).isTrue(); |
| |
| wasCalled.set(false); |
| matchesTypeSafe().apply(new TestMatcher(), ""); |
| assertThat(wasCalled.get()).isFalse(); |
| } |
| |
| @Test |
| public void passEveryArgumentTypeIfNoBridgeMethodWasGenerated() { |
| final AtomicBoolean wasCalled = new AtomicBoolean(); |
| class GenericMatcher<T> implements ArgumentMatcher<T> { |
| @Override |
| public boolean matches(T argument) { |
| wasCalled.set(true); |
| return true; |
| } |
| } |
| |
| wasCalled.set(false); |
| matchesTypeSafe().apply(new GenericMatcher<Integer>(), 123); |
| assertThat(wasCalled.get()).isTrue(); |
| |
| wasCalled.set(false); |
| matchesTypeSafe().apply(new GenericMatcher<Integer>(), ""); |
| assertThat(wasCalled.get()).isTrue(); |
| } |
| } |