1/*
2 * Copyright (c) 2007 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5
6package org.mockito.internal.invocation;
7
8import static java.util.Arrays.asList;
9import static junit.framework.TestCase.assertEquals;
10import static junit.framework.TestCase.assertFalse;
11import static junit.framework.TestCase.assertTrue;
12import static org.assertj.core.api.Assertions.assertThat;
13import static org.mockito.internal.matchers.Any.ANY;
14
15import java.lang.reflect.Method;
16import java.util.Arrays;
17import java.util.HashMap;
18import java.util.List;
19import java.util.Map;
20import org.assertj.core.api.Assertions;
21import org.junit.Before;
22import org.junit.Test;
23import org.mockito.ArgumentMatcher;
24import org.mockito.Mock;
25import org.mockito.internal.matchers.CapturingMatcher;
26import org.mockito.internal.matchers.Equals;
27import org.mockito.internal.matchers.NotNull;
28import org.mockito.invocation.Invocation;
29import org.mockitousage.IMethods;
30import org.mockitoutil.TestBase;
31
32@SuppressWarnings("unchecked")
33public class InvocationMatcherTest extends TestBase {
34
35    private InvocationMatcher simpleMethod;
36    @Mock private IMethods mock;
37
38    @Before
39    public void setup() {
40        simpleMethod = new InvocationBuilder().mock(mock).simpleMethod().toInvocationMatcher();
41    }
42
43    @Test
44    public void should_be_a_citizen_of_hashes() throws Exception {
45        Invocation invocation = new InvocationBuilder().toInvocation();
46        Invocation invocationTwo = new InvocationBuilder().args("blah").toInvocation();
47
48        Map<InvocationMatcher, String> map = new HashMap<InvocationMatcher, String>();
49        map.put(new InvocationMatcher(invocation), "one");
50        map.put(new InvocationMatcher(invocationTwo), "two");
51
52        assertEquals(2, map.size());
53    }
54
55    @Test
56    public void should_not_equal_if_number_of_arguments_differ() throws Exception {
57        InvocationMatcher withOneArg = new InvocationMatcher(new InvocationBuilder().args("test").toInvocation());
58        InvocationMatcher withTwoArgs = new InvocationMatcher(new InvocationBuilder().args("test", 100).toInvocation());
59
60        assertFalse(withOneArg.equals(null));
61        assertFalse(withOneArg.equals(withTwoArgs));
62    }
63
64    @Test
65    public void should_to_string_with_matchers() throws Exception {
66        ArgumentMatcher m = NotNull.NOT_NULL;
67        InvocationMatcher notNull = new InvocationMatcher(new InvocationBuilder().toInvocation(), asList(m));
68        ArgumentMatcher mTwo = new Equals('x');
69        InvocationMatcher equals = new InvocationMatcher(new InvocationBuilder().toInvocation(), asList(mTwo));
70
71        assertThat(notNull.toString()).contains("simpleMethod(notNull())");
72        assertThat(equals.toString()).contains("simpleMethod('x')");
73    }
74
75    @Test
76    public void should_know_if_is_similar_to() throws Exception {
77        Invocation same = new InvocationBuilder().mock(mock).simpleMethod().toInvocation();
78        assertTrue(simpleMethod.hasSimilarMethod(same));
79
80        Invocation different = new InvocationBuilder().mock(mock).differentMethod().toInvocation();
81        assertFalse(simpleMethod.hasSimilarMethod(different));
82    }
83
84    @Test
85    public void should_not_be_similar_to_verified_invocation() throws Exception {
86        Invocation verified = new InvocationBuilder().simpleMethod().verified().toInvocation();
87        assertFalse(simpleMethod.hasSimilarMethod(verified));
88    }
89
90    @Test
91    public void should_not_be_similar_if_mocks_are_different() throws Exception {
92        Invocation onDifferentMock = new InvocationBuilder().simpleMethod().mock("different mock").toInvocation();
93        assertFalse(simpleMethod.hasSimilarMethod(onDifferentMock));
94    }
95
96    @Test
97    public void should_not_be_similar_if_is_overloaded_but_used_with_the_same_arg() throws Exception {
98        Method method = IMethods.class.getMethod("simpleMethod", String.class);
99        Method overloadedMethod = IMethods.class.getMethod("simpleMethod", Object.class);
100
101        String sameArg = "test";
102
103        InvocationMatcher invocation = new InvocationBuilder().method(method).arg(sameArg).toInvocationMatcher();
104        Invocation overloadedInvocation = new InvocationBuilder().method(overloadedMethod).arg(sameArg).toInvocation();
105
106        assertFalse(invocation.hasSimilarMethod(overloadedInvocation));
107    }
108
109    @Test
110    public void should_be_similar_if_is_overloaded_but_used_with_different_arg() throws Exception {
111        Method method = IMethods.class.getMethod("simpleMethod", String.class);
112        Method overloadedMethod = IMethods.class.getMethod("simpleMethod", Object.class);
113
114        InvocationMatcher invocation = new InvocationBuilder().mock(mock).method(method).arg("foo").toInvocationMatcher();
115        Invocation overloadedInvocation = new InvocationBuilder().mock(mock).method(overloadedMethod).arg("bar").toInvocation();
116
117        assertTrue(invocation.hasSimilarMethod(overloadedInvocation));
118    }
119
120    @Test
121    public void should_capture_arguments_from_invocation() throws Exception {
122        //given
123        Invocation invocation = new InvocationBuilder().args("1", 100).toInvocation();
124        CapturingMatcher capturingMatcher = new CapturingMatcher();
125        InvocationMatcher invocationMatcher = new InvocationMatcher(invocation, (List) asList(new Equals("1"), capturingMatcher));
126
127        //when
128        invocationMatcher.captureArgumentsFrom(invocation);
129
130        //then
131        assertEquals(1, capturingMatcher.getAllValues().size());
132        assertEquals(100, capturingMatcher.getLastValue());
133    }
134
135    @Test
136    public void should_match_varargs_using_any_varargs() throws Exception {
137        //given
138        mock.varargs("1", "2");
139        Invocation invocation = getLastInvocation();
140        InvocationMatcher invocationMatcher = new InvocationMatcher(invocation, (List) asList(ANY));
141
142        //when
143        boolean match = invocationMatcher.matches(invocation);
144
145        //then
146        assertTrue(match);
147    }
148
149    @Test
150    public void should_capture_varargs_as_vararg() throws Exception {
151        //given
152        mock.mixedVarargs(1, "a", "b");
153        Invocation invocation = getLastInvocation();
154        CapturingMatcher m = new CapturingMatcher();
155        InvocationMatcher invocationMatcher = new InvocationMatcher(invocation, Arrays.<ArgumentMatcher>asList(new Equals(1), m));
156
157        //when
158        invocationMatcher.captureArgumentsFrom(invocation);
159
160        //then
161        Assertions.assertThat(m.getAllValues()).containsExactly("a", "b");
162    }
163
164    @Test  // like using several time the captor in the vararg
165    public void should_capture_arguments_when_args_count_does_NOT_match() throws Exception {
166        //given
167        mock.varargs();
168        Invocation invocation = getLastInvocation();
169
170        //when
171        InvocationMatcher invocationMatcher = new InvocationMatcher(invocation,(List) asList(ANY));
172
173        //then
174        invocationMatcher.captureArgumentsFrom(invocation);
175    }
176
177    @Test
178    public void should_create_from_invocations() throws Exception {
179        //given
180        Invocation i = new InvocationBuilder().toInvocation();
181        //when
182        List<InvocationMatcher> out = InvocationMatcher.createFrom(asList(i));
183        //then
184        assertEquals(1, out.size());
185        assertEquals(i, out.get(0).getInvocation());
186    }
187}
188