/* * Copyright (c) 2007 Mockito contributors * This program is made available under the terms of the MIT License. */ package org.mockitousage.matchers; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.RandomAccess; import java.util.regex.Pattern; import org.junit.Test; import org.mockito.Mockito; import org.mockito.exceptions.verification.WantedButNotInvoked; import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent; import org.mockitousage.IMethods; import org.mockitoutil.TestBase; import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertNotSame; import static junit.framework.TestCase.fail; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.AdditionalMatchers.and; import static org.mockito.AdditionalMatchers.aryEq; import static org.mockito.AdditionalMatchers.cmpEq; import static org.mockito.AdditionalMatchers.eq; import static org.mockito.AdditionalMatchers.find; import static org.mockito.AdditionalMatchers.geq; import static org.mockito.AdditionalMatchers.gt; import static org.mockito.AdditionalMatchers.leq; import static org.mockito.AdditionalMatchers.lt; import static org.mockito.AdditionalMatchers.not; import static org.mockito.AdditionalMatchers.or; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyByte; import static org.mockito.Mockito.anyChar; import static org.mockito.Mockito.anyDouble; import static org.mockito.Mockito.anyFloat; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.anyObject; import static org.mockito.Mockito.anyShort; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.contains; import static org.mockito.Mockito.endsWith; import static org.mockito.Mockito.isA; import static org.mockito.Mockito.isNotNull; import static org.mockito.Mockito.isNull; import static org.mockito.Mockito.matches; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.notNull; import static org.mockito.Mockito.same; import static org.mockito.Mockito.startsWith; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @SuppressWarnings("unchecked") public class MatchersTest extends TestBase { private IMethods mock = Mockito.mock(IMethods.class); @Test public void and_overloaded() { when(mock.oneArg(and(eq(false), eq(false)))).thenReturn("0"); when(mock.oneArg(and(eq((byte) 1), eq((byte) 1)))).thenReturn("1"); when(mock.oneArg(and(eq('a'), eq('a')))).thenReturn("2"); when(mock.oneArg(and(eq((double) 1), eq((double) 1)))).thenReturn("3"); when(mock.oneArg(and(eq((float) 1), eq((float) 1)))).thenReturn("4"); when(mock.oneArg(and(eq((int) 1), eq((int) 1)))).thenReturn("5"); when(mock.oneArg(and(eq((long) 1), eq((long) 1)))).thenReturn("6"); when(mock.oneArg(and(eq((short) 1), eq((short) 1)))).thenReturn("7"); when(mock.oneArg(and(contains("a"), contains("d")))).thenReturn("8"); when(mock.oneArg(and(isA(Class.class), eq(Object.class)))).thenReturn("9"); assertEquals("0", mock.oneArg(false)); assertEquals(null, mock.oneArg(true)); assertEquals("1", mock.oneArg((byte) 1)); assertEquals("2", mock.oneArg('a')); assertEquals("3", mock.oneArg((double) 1)); assertEquals("4", mock.oneArg((float) 1)); assertEquals("5", mock.oneArg((int) 1)); assertEquals("6", mock.oneArg((long) 1)); assertEquals("7", mock.oneArg((short) 1)); assertEquals("8", mock.oneArg("abcde")); assertEquals(null, mock.oneArg("aaaaa")); assertEquals("9", mock.oneArg(Object.class)); } @Test public void or_overloaded() { when(mock.oneArg(or(eq(false), eq(true)))).thenReturn("0"); when(mock.oneArg(or(eq((byte) 1), eq((byte) 2)))).thenReturn("1"); when(mock.oneArg(or(eq((char) 1), eq((char) 2)))).thenReturn("2"); when(mock.oneArg(or(eq((double) 1), eq((double) 2)))).thenReturn("3"); when(mock.oneArg(or(eq((float) 1), eq((float) 2)))).thenReturn("4"); when(mock.oneArg(or(eq((int) 1), eq((int) 2)))).thenReturn("5"); when(mock.oneArg(or(eq((long) 1), eq((long) 2)))).thenReturn("6"); when(mock.oneArg(or(eq((short) 1), eq((short) 2)))).thenReturn("7"); when(mock.oneArg(or(eq("asd"), eq("jkl")))).thenReturn("8"); when(mock.oneArg(or(eq(this.getClass()), eq(Object.class)))).thenReturn("9"); assertEquals("0", mock.oneArg(true)); assertEquals("0", mock.oneArg(false)); assertEquals("1", mock.oneArg((byte) 2)); assertEquals("2", mock.oneArg((char) 1)); assertEquals("3", mock.oneArg((double) 2)); assertEquals("4", mock.oneArg((float) 1)); assertEquals("5", mock.oneArg((int) 2)); assertEquals("6", mock.oneArg((long) 1)); assertEquals("7", mock.oneArg((short) 1)); assertEquals("8", mock.oneArg("jkl")); assertEquals("8", mock.oneArg("asd")); assertEquals(null, mock.oneArg("asdjkl")); assertEquals("9", mock.oneArg(Object.class)); assertEquals(null, mock.oneArg(String.class)); } @Test public void not_overloaded() { when(mock.oneArg(not(eq(false)))).thenReturn("0"); when(mock.oneArg(not(eq((byte) 1)))).thenReturn("1"); when(mock.oneArg(not(eq('a')))).thenReturn("2"); when(mock.oneArg(not(eq((double) 1)))).thenReturn("3"); when(mock.oneArg(not(eq((float) 1)))).thenReturn("4"); when(mock.oneArg(not(eq((int) 1)))).thenReturn("5"); when(mock.oneArg(not(eq((long) 1)))).thenReturn("6"); when(mock.oneArg(not(eq((short) 1)))).thenReturn("7"); when(mock.oneArg(not(contains("a")))).thenReturn("8"); when(mock.oneArg(not(isA(Class.class)))).thenReturn("9"); assertEquals("0", mock.oneArg(true)); assertEquals(null, mock.oneArg(false)); assertEquals("1", mock.oneArg((byte) 2)); assertEquals("2", mock.oneArg('b')); assertEquals("3", mock.oneArg((double) 2)); assertEquals("4", mock.oneArg((float) 2)); assertEquals("5", mock.oneArg((int) 2)); assertEquals("6", mock.oneArg((long) 2)); assertEquals("7", mock.oneArg((short) 2)); assertEquals("8", mock.oneArg("bcde")); assertEquals("9", mock.oneArg(new Object())); assertEquals(null, mock.oneArg(Class.class)); } @Test public void less_or_equal_overloaded() { when(mock.oneArg(leq((byte) 1))).thenReturn("1"); when(mock.oneArg(leq((double) 1))).thenReturn("3"); when(mock.oneArg(leq((float) 1))).thenReturn("4"); when(mock.oneArg(leq((int) 1))).thenReturn("5"); when(mock.oneArg(leq((long) 1))).thenReturn("6"); when(mock.oneArg(leq((short) 1))).thenReturn("7"); when(mock.oneArg(leq(new BigDecimal("1")))).thenReturn("8"); assertEquals("1", mock.oneArg((byte) 1)); assertEquals(null, mock.oneArg((byte) 2)); assertEquals("3", mock.oneArg((double) 1)); assertEquals("7", mock.oneArg((short) 0)); assertEquals("4", mock.oneArg((float) -5)); assertEquals("5", mock.oneArg((int) -2)); assertEquals("6", mock.oneArg((long) -3)); assertEquals("8", mock.oneArg(new BigDecimal("0.5"))); assertEquals(null, mock.oneArg(new BigDecimal("1.1"))); } @Test public void less_than_overloaded() { when(mock.oneArg(lt((byte) 1))).thenReturn("1"); when(mock.oneArg(lt((double) 1))).thenReturn("3"); when(mock.oneArg(lt((float) 1))).thenReturn("4"); when(mock.oneArg(lt((int) 1))).thenReturn("5"); when(mock.oneArg(lt((long) 1))).thenReturn("6"); when(mock.oneArg(lt((short) 1))).thenReturn("7"); when(mock.oneArg(lt(new BigDecimal("1")))).thenReturn("8"); assertEquals("1", mock.oneArg((byte) 0)); assertEquals(null, mock.oneArg((byte) 1)); assertEquals("3", mock.oneArg((double) 0)); assertEquals("7", mock.oneArg((short) 0)); assertEquals("4", mock.oneArg((float) -4)); assertEquals("5", mock.oneArg((int) -34)); assertEquals("6", mock.oneArg((long) -6)); assertEquals("8", mock.oneArg(new BigDecimal("0.5"))); assertEquals(null, mock.oneArg(new BigDecimal("23"))); } @Test public void greater_or_equal_matcher_overloaded() { when(mock.oneArg(geq((byte) 1))).thenReturn("1"); when(mock.oneArg(geq((double) 1))).thenReturn("3"); when(mock.oneArg(geq((float) 1))).thenReturn("4"); when(mock.oneArg(geq((int) 1))).thenReturn("5"); when(mock.oneArg(geq((long) 1))).thenReturn("6"); when(mock.oneArg(geq((short) 1))).thenReturn("7"); when(mock.oneArg(geq(new BigDecimal("1")))).thenReturn("8"); assertEquals("1", mock.oneArg((byte) 2)); assertEquals(null, mock.oneArg((byte) 0)); assertEquals("3", mock.oneArg((double) 1)); assertEquals("7", mock.oneArg((short) 2)); assertEquals("4", mock.oneArg((float) 3)); assertEquals("5", mock.oneArg((int) 4)); assertEquals("6", mock.oneArg((long) 5)); assertEquals("8", mock.oneArg(new BigDecimal("1.00"))); assertEquals(null, mock.oneArg(new BigDecimal("0.9"))); } @Test public void greater_than_matcher_overloaded() { when(mock.oneArg(gt((byte) 1))).thenReturn("1"); when(mock.oneArg(gt((double) 1))).thenReturn("3"); when(mock.oneArg(gt((float) 1))).thenReturn("4"); when(mock.oneArg(gt((int) 1))).thenReturn("5"); when(mock.oneArg(gt((long) 1))).thenReturn("6"); when(mock.oneArg(gt((short) 1))).thenReturn("7"); when(mock.oneArg(gt(new BigDecimal("1")))).thenReturn("8"); assertEquals("1", mock.oneArg((byte) 2)); assertEquals(null, mock.oneArg((byte) 1)); assertEquals("3", mock.oneArg((double) 2)); assertEquals("7", mock.oneArg((short) 2)); assertEquals("4", mock.oneArg((float) 3)); assertEquals("5", mock.oneArg((int) 2)); assertEquals("6", mock.oneArg((long) 5)); assertEquals("8", mock.oneArg(new BigDecimal("1.5"))); assertEquals(null, mock.oneArg(new BigDecimal("0.9"))); } @Test public void compare_to_matcher() { when(mock.oneArg(cmpEq(new BigDecimal("1.5")))).thenReturn("0"); assertEquals("0", mock.oneArg(new BigDecimal("1.50"))); assertEquals(null, mock.oneArg(new BigDecimal("1.51"))); } @Test public void any_String_matcher() { when(mock.oneArg(anyString())).thenReturn("matched"); assertEquals("matched", mock.oneArg("")); assertEquals("matched", mock.oneArg("any string")); assertEquals(null, mock.oneArg((String) null)); } @Test public void any_matcher() { when(mock.forObject(any())).thenReturn("matched"); assertEquals("matched", mock.forObject(123)); assertEquals("matched", mock.forObject("any string")); assertEquals("matched", mock.forObject("any string")); assertEquals("matched", mock.forObject((Object) null)); } @Test public void any_T_matcher() { when(mock.oneArg(anyBoolean())).thenReturn("0"); when(mock.oneArg(anyByte())).thenReturn("1"); when(mock.oneArg(anyChar())).thenReturn("2"); when(mock.oneArg(anyDouble())).thenReturn("3"); when(mock.oneArg(anyFloat())).thenReturn("4"); when(mock.oneArg(anyInt())).thenReturn("5"); when(mock.oneArg(anyLong())).thenReturn("6"); when(mock.oneArg(anyShort())).thenReturn("7"); when(mock.oneArg((String) anyObject())).thenReturn("8"); when(mock.oneArg((Object) anyObject())).thenReturn("9"); when(mock.oneArg(any(RandomAccess.class))).thenReturn("10"); assertEquals("0", mock.oneArg(true)); assertEquals("0", mock.oneArg(false)); assertEquals("1", mock.oneArg((byte) 1)); assertEquals("2", mock.oneArg((char) 1)); assertEquals("3", mock.oneArg((double) 1)); assertEquals("4", mock.oneArg((float) 889)); assertEquals("5", mock.oneArg((int) 1)); assertEquals("6", mock.oneArg((long) 1)); assertEquals("7", mock.oneArg((short) 1)); assertEquals("8", mock.oneArg("Test")); assertEquals("9", mock.oneArg(new Object())); assertEquals("9", mock.oneArg(new HashMap())); assertEquals("10", mock.oneArg(new ArrayList())); } @Test public void should_array_equals_deal_with_null_array() throws Exception { Object[] nullArray = null; when(mock.oneArray(aryEq(nullArray))).thenReturn("null"); assertEquals("null", mock.oneArray(nullArray)); mock = mock(IMethods.class); try { verify(mock).oneArray(aryEq(nullArray)); fail(); } catch (WantedButNotInvoked e) { assertThat(e).hasMessageContaining("oneArray(null)"); } } @Test public void should_use_smart_equals_for_arrays() throws Exception { //issue 143 mock.arrayMethod(new String[]{"one"}); verify(mock).arrayMethod(eq(new String[]{"one"})); verify(mock).arrayMethod(new String[]{"one"}); } @Test public void should_use_smart_equals_for_primitive_arrays() throws Exception { //issue 143 mock.objectArgMethod(new int[]{1, 2}); verify(mock).objectArgMethod(eq(new int[]{1, 2})); verify(mock).objectArgMethod(new int[]{1, 2}); } @Test(expected = ArgumentsAreDifferent.class) public void array_equals_should_throw_ArgumentsAreDifferentException_for_non_matching_arguments() { List list = Mockito.mock(List.class); list.add("test"); // testing fix for issue 20 list.contains(new Object[]{"1"}); Mockito.verify(list).contains(new Object[]{"1", "2", "3"}); } @Test public void array_equals_matcher() { when(mock.oneArray(aryEq(new boolean[]{true, false, false}))).thenReturn("0"); when(mock.oneArray(aryEq(new byte[]{1}))).thenReturn("1"); when(mock.oneArray(aryEq(new char[]{1}))).thenReturn("2"); when(mock.oneArray(aryEq(new double[]{1}))).thenReturn("3"); when(mock.oneArray(aryEq(new float[]{1}))).thenReturn("4"); when(mock.oneArray(aryEq(new int[]{1}))).thenReturn("5"); when(mock.oneArray(aryEq(new long[]{1}))).thenReturn("6"); when(mock.oneArray(aryEq(new short[]{1}))).thenReturn("7"); when(mock.oneArray(aryEq(new String[]{"Test"}))).thenReturn("8"); when(mock.oneArray(aryEq(new Object[]{"Test", new Integer(4)}))).thenReturn("9"); assertEquals("0", mock.oneArray(new boolean[]{true, false, false})); assertEquals("1", mock.oneArray(new byte[]{1})); assertEquals("2", mock.oneArray(new char[]{1})); assertEquals("3", mock.oneArray(new double[]{1})); assertEquals("4", mock.oneArray(new float[]{1})); assertEquals("5", mock.oneArray(new int[]{1})); assertEquals("6", mock.oneArray(new long[]{1})); assertEquals("7", mock.oneArray(new short[]{1})); assertEquals("8", mock.oneArray(new String[]{"Test"})); assertEquals("9", mock.oneArray(new Object[]{"Test", new Integer(4)})); assertEquals(null, mock.oneArray(new Object[]{"Test", new Integer(999)})); assertEquals(null, mock.oneArray(new Object[]{"Test", new Integer(4), "x"})); assertEquals(null, mock.oneArray(new boolean[]{true, false})); assertEquals(null, mock.oneArray(new boolean[]{true, true, false})); } @Test public void greater_or_equal_matcher() { when(mock.oneArg(geq(7))).thenReturn(">= 7"); when(mock.oneArg(lt(7))).thenReturn("< 7"); assertEquals(">= 7", mock.oneArg(7)); assertEquals(">= 7", mock.oneArg(8)); assertEquals(">= 7", mock.oneArg(9)); assertEquals("< 7", mock.oneArg(6)); assertEquals("< 7", mock.oneArg(6)); } @Test public void greater_than_matcher() { when(mock.oneArg(gt(7))).thenReturn("> 7"); when(mock.oneArg(leq(7))).thenReturn("<= 7"); assertEquals("> 7", mock.oneArg(8)); assertEquals("> 7", mock.oneArg(9)); assertEquals("> 7", mock.oneArg(10)); assertEquals("<= 7", mock.oneArg(7)); assertEquals("<= 7", mock.oneArg(6)); } @Test public void less_or_equal_matcher() { when(mock.oneArg(leq(7))).thenReturn("<= 7"); when(mock.oneArg(gt(7))).thenReturn("> 7"); assertEquals("<= 7", mock.oneArg(7)); assertEquals("<= 7", mock.oneArg(6)); assertEquals("<= 7", mock.oneArg(5)); assertEquals("> 7", mock.oneArg(8)); assertEquals("> 7", mock.oneArg(9)); } @Test public void less_than_matcher() { when(mock.oneArg(lt(7))).thenReturn("< 7"); when(mock.oneArg(geq(7))).thenReturn(">= 7"); assertEquals("< 7", mock.oneArg(5)); assertEquals("< 7", mock.oneArg(6)); assertEquals("< 7", mock.oneArg(4)); assertEquals(">= 7", mock.oneArg(7)); assertEquals(">= 7", mock.oneArg(8)); } @Test public void or_matcher() { when(mock.oneArg(anyInt())).thenReturn("other"); when(mock.oneArg(or(eq(7), eq(9)))).thenReturn("7 or 9"); assertEquals("other", mock.oneArg(10)); assertEquals("7 or 9", mock.oneArg(7)); assertEquals("7 or 9", mock.oneArg(9)); } @Test public void null_matcher() { when(mock.threeArgumentMethod(eq(1), isNull(), eq(""))).thenReturn("1"); when(mock.threeArgumentMethod(eq(1), not(isNull()), eq(""))).thenReturn("2"); assertEquals("1", mock.threeArgumentMethod(1, null, "")); assertEquals("2", mock.threeArgumentMethod(1, new Object(), "")); } @Test public void null_matcher_for_primitive_wrappers() { when(mock.forBoolean(isNull(Boolean.class))).thenReturn("ok"); when(mock.forInteger(isNull(Integer.class))).thenReturn("ok"); when(mock.forLong(isNull(Long.class))).thenReturn("ok"); when(mock.forByte(isNull(Byte.class))).thenReturn("ok"); when(mock.forShort(isNull(Short.class))).thenReturn("ok"); when(mock.forCharacter(isNull(Character.class))).thenReturn("ok"); when(mock.forDouble(isNull(Double.class))).thenReturn("ok"); when(mock.forFloat(isNull(Float.class))).thenReturn("ok"); assertEquals("ok", mock.forBoolean(null)); assertEquals("ok", mock.forInteger(null)); assertEquals("ok", mock.forLong(null)); assertEquals("ok", mock.forByte(null)); assertEquals("ok", mock.forShort(null)); assertEquals("ok", mock.forCharacter(null)); assertEquals("ok", mock.forDouble(null)); assertEquals("ok", mock.forFloat(null)); } @Test public void not_null_matcher() { when(mock.threeArgumentMethod(eq(1), notNull(), eq(""))).thenReturn("1"); when(mock.threeArgumentMethod(eq(1), not(isNotNull()), eq(""))).thenReturn("2"); assertEquals("1", mock.threeArgumentMethod(1, new Object(), "")); assertEquals("2", mock.threeArgumentMethod(1, null, "")); } @Test public void find_matcher() { when(mock.oneArg(find("([a-z]+)\\d"))).thenReturn("1"); assertEquals("1", mock.oneArg("ab12")); assertEquals(null, mock.oneArg("12345")); assertEquals(null, mock.oneArg((Object) null)); } @Test public void matches_matcher() { when(mock.oneArg(matches("[a-z]+\\d\\d"))).thenReturn("1"); when(mock.oneArg(matches("\\d\\d\\d"))).thenReturn("2"); assertEquals("1", mock.oneArg("a12")); assertEquals("2", mock.oneArg("131")); assertEquals(null, mock.oneArg("blah")); } @Test public void matches_Pattern_matcher() { when(mock.oneArg(matches(Pattern.compile("[a-z]+\\d\\d")))).thenReturn("1"); when(mock.oneArg(matches(Pattern.compile("\\d\\d\\d")))).thenReturn("2"); assertEquals("1", mock.oneArg("a12")); assertEquals("2", mock.oneArg("131")); assertEquals(null, mock.oneArg("blah")); } @Test public void contains_matcher() { when(mock.oneArg(contains("ell"))).thenReturn("1"); when(mock.oneArg(contains("ld"))).thenReturn("2"); assertEquals("1", mock.oneArg("hello")); assertEquals("2", mock.oneArg("world")); assertEquals(null, mock.oneArg("xlx")); } @Test public void starts_with_matcher() { when(mock.oneArg(startsWith("ab"))).thenReturn("1"); when(mock.oneArg(startsWith("bc"))).thenReturn("2"); assertEquals("1", mock.oneArg("ab quake")); assertEquals("2", mock.oneArg("bc quake")); assertEquals(null, mock.oneArg("ba quake")); } @Test public void ends_with_matcher() { when(mock.oneArg(endsWith("ab"))).thenReturn("1"); when(mock.oneArg(endsWith("bc"))).thenReturn("2"); assertEquals("1", mock.oneArg("xab")); assertEquals("2", mock.oneArg("xbc")); assertEquals(null, mock.oneArg("ac")); } @Test public void delta_matcher() { when(mock.oneArg(eq(1.0D, 0.1D))).thenReturn("1"); when(mock.oneArg(eq(2.0D, 0.1D))).thenReturn("2"); when(mock.oneArg(eq(1.0F, 0.1F))).thenReturn("3"); when(mock.oneArg(eq(2.0F, 0.1F))).thenReturn("4"); when(mock.oneArg(eq(2.0F, 0.1F))).thenReturn("4"); assertEquals("1", mock.oneArg(1.0)); assertEquals("1", mock.oneArg(0.91)); assertEquals("1", mock.oneArg(1.09)); assertEquals("2", mock.oneArg(2.0)); assertEquals("3", mock.oneArg(1.0F)); assertEquals("3", mock.oneArg(0.91F)); assertEquals("3", mock.oneArg(1.09F)); assertEquals("4", mock.oneArg(2.1F)); assertEquals(null, mock.oneArg(2.2F)); } @Test public void delta_matcher_prints_itself() { try { verify(mock).oneArg(eq(1.0D, 0.1D)); fail(); } catch (WantedButNotInvoked e) { assertThat(e).hasMessageContaining("eq(1.0, 0.1)"); } } @Test public void same_matcher() { Object one = new String("1243"); Object two = new String("1243"); Object three = new String("1243"); assertNotSame(one, two); assertEquals(one, two); assertEquals(two, three); when(mock.oneArg(same(one))).thenReturn("1"); when(mock.oneArg(same(two))).thenReturn("2"); assertEquals("1", mock.oneArg(one)); assertEquals("2", mock.oneArg(two)); assertEquals(null, mock.oneArg(three)); } @Test public void eq_matcher_and_nulls() { mock.simpleMethod((Object) null); verify(mock).simpleMethod((Object) eq(null)); } @Test public void same_matcher_and_nulls() { mock.simpleMethod((Object) null); verify(mock).simpleMethod((Object) same(null)); } @Test public void nullable_matcher() throws Exception { // imagine a Stream.of(...).map(c -> mock.oneArg(c))... mock.oneArg((Character) null); mock.oneArg(Character.valueOf('€')); verify(mock, times(2)).oneArg(nullable(Character.class)); } }