1/* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5package org.mockito.internal.invocation; 6 7import static java.util.Arrays.asList; 8import static org.junit.Assert.assertFalse; 9import static org.junit.Assert.assertTrue; 10import static org.assertj.core.api.Assertions.assertThat; 11import static org.mockito.internal.invocation.MatcherApplicationStrategy.getMatcherApplicationStrategyFor; 12import static org.mockito.internal.matchers.Any.ANY; 13 14import java.util.ArrayList; 15import java.util.List; 16 17import org.junit.Before; 18import org.junit.Test; 19import org.mockito.ArgumentMatcher; 20import org.mockito.Mock; 21import org.mockito.internal.matchers.Any; 22import org.mockito.internal.matchers.Equals; 23import org.mockito.internal.matchers.InstanceOf; 24import org.mockito.invocation.Invocation; 25import org.mockitousage.IMethods; 26import org.mockitoutil.TestBase; 27 28@SuppressWarnings("unchecked") 29public class MatcherApplicationStrategyTest extends TestBase { 30 31 @Mock 32 IMethods mock; 33 private Invocation invocation; 34 private List matchers; 35 36 private RecordingAction recordAction; 37 38 @Before 39 public void before() { 40 recordAction = new RecordingAction(); 41 } 42 43 @Test 44 public void shouldKnowWhenActualArgsSizeIsDifferent1() { 45 // given 46 invocation = varargs("1"); 47 matchers = asList(new Equals("1")); 48 49 // when 50 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(RETURN_ALWAYS_FALSE); 51 52 // then 53 assertFalse(match); 54 } 55 56 @Test 57 public void shouldKnowWhenActualArgsSizeIsDifferent2() { 58 // given 59 invocation = varargs("1"); 60 matchers = asList(new Equals("1")); 61 62 // when 63 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(RETURN_ALWAYS_TRUE); 64 65 // then 66 assertTrue(match); 67 } 68 69 @Test 70 public void shouldKnowWhenActualArgsSizeIsDifferent() { 71 // given 72 invocation = varargs("1", "2"); 73 matchers = asList(new Equals("1")); 74 75 // when 76 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(RETURN_ALWAYS_TRUE); 77 78 // then 79 assertFalse(match); 80 } 81 82 @Test 83 public void shouldKnowWhenMatchersSizeIsDifferent() { 84 // given 85 invocation = varargs("1"); 86 matchers = asList(new Equals("1"), new Equals("2")); 87 88 // when 89 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(RETURN_ALWAYS_TRUE); 90 91 // then 92 assertFalse(match); 93 } 94 95 @Test 96 public void shouldKnowWhenVarargsMatch() { 97 // given 98 invocation = varargs("1", "2", "3"); 99 matchers = asList(new Equals("1"), Any.ANY, new InstanceOf(String.class)); 100 101 // when 102 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(recordAction); 103 104 // then 105 assertTrue(match); 106 } 107 108 @Test 109 public void shouldAllowAnyVarargMatchEntireVararg() { 110 // given 111 invocation = varargs("1", "2"); 112 matchers = asList(ANY); 113 114 // when 115 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(recordAction); 116 117 // then 118 assertTrue(match); 119 } 120 121 @Test 122 public void shouldNotAllowAnyObjectWithMixedVarargs() { 123 // given 124 invocation = mixedVarargs(1, "1", "2"); 125 matchers = asList(new Equals(1)); 126 127 // when 128 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(recordAction); 129 130 // then 131 assertFalse(match); 132 } 133 134 @Test 135 public void shouldAllowAnyObjectWithMixedVarargs() { 136 // given 137 invocation = mixedVarargs(1, "1", "2"); 138 matchers = asList(new Equals(1), ANY); 139 140 // when 141 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(recordAction); 142 143 // then 144 assertTrue(match); 145 } 146 147 @Test 148 public void shouldAnyObjectVarargDealWithDifferentSizeOfArgs() { 149 // given 150 invocation = mixedVarargs(1, "1", "2"); 151 matchers = asList(new Equals(1)); 152 153 // when 154 boolean match = getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(recordAction); 155 156 // then 157 assertFalse(match); 158 159 recordAction.assertIsEmpty(); 160 } 161 162 @Test 163 public void shouldMatchAnyVarargEvenIfOneOfTheArgsIsNull() { 164 // given 165 invocation = mixedVarargs(null, null, "2"); 166 matchers = asList(new Equals(null), ANY); 167 168 // when 169 getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(recordAction); 170 171 // then 172 recordAction.assertContainsExactly(new Equals(null), ANY, ANY); 173 174 } 175 176 @Test 177 public void shouldMatchAnyVarargEvenIfMatcherIsDecorated() { 178 // given 179 invocation = varargs("1", "2"); 180 matchers = asList(ANY); 181 182 // when 183 getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(recordAction); 184 185 // then 186 recordAction.assertContainsExactly(ANY, ANY); 187 } 188 189 private Invocation mixedVarargs(Object a, String... s) { 190 mock.mixedVarargs(a, s); 191 return getLastInvocation(); 192 } 193 194 private Invocation varargs(String... s) { 195 mock.varargs(s); 196 return getLastInvocation(); 197 } 198 199 private class RecordingAction implements ArgumentMatcherAction { 200 private List<ArgumentMatcher<?>> matchers = new ArrayList<ArgumentMatcher<?>>(); 201 202 @Override 203 public boolean apply(ArgumentMatcher<?> matcher, Object argument) { 204 matchers.add(matcher); 205 return true; 206 } 207 208 public void assertIsEmpty() { 209 assertThat(matchers).isEmpty(); 210 } 211 212 public void assertContainsExactly(ArgumentMatcher<?>... matchers) { 213 assertThat(this.matchers).containsExactly(matchers); 214 } 215 } 216 217 private static final ArgumentMatcherAction RETURN_ALWAYS_TRUE = new ArgumentMatcherAction() { 218 @Override 219 public boolean apply(ArgumentMatcher<?> matcher, Object argument) { 220 return true; 221 } 222 }; 223 224 private static final ArgumentMatcherAction RETURN_ALWAYS_FALSE = new ArgumentMatcherAction() { 225 @Override 226 public boolean apply(ArgumentMatcher<?> matcher, Object argument) { 227 return false; 228 } 229 }; 230 231} 232