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 org.assertj.core.api.Assertions;
9import org.junit.Before;
10import org.junit.Test;
11import org.mockito.exceptions.base.MockitoException;
12import org.mockito.internal.invocation.realmethod.RealMethod;
13import org.mockito.internal.matchers.ArrayEquals;
14import org.mockito.internal.matchers.Equals;
15import org.mockito.invocation.Invocation;
16import org.mockitousage.IMethods;
17import org.mockitoutil.TestBase;
18
19import java.lang.reflect.Method;
20import java.util.HashMap;
21import java.util.List;
22import java.util.Map;
23
24import static junit.framework.TestCase.*;
25
26@SuppressWarnings({"unchecked"})
27public class InvocationImplTest extends TestBase {
28
29    private Invocation invocation;
30
31    @Before
32    public void setup() throws Exception {
33        invocation = new InvocationBuilder().args(" ").mock("mock").toInvocation();
34    }
35
36    @Test
37    public void shouldKnowIfIsEqualTo() {
38        Invocation equal =                  new InvocationBuilder().args(" ").mock("mock").toInvocation();
39        Invocation nonEqual =               new InvocationBuilder().args("X").mock("mock").toInvocation();
40        Invocation withNewStringInstance =  new InvocationBuilder().args(new String(" ")).mock("mock").toInvocation();
41
42        assertFalse(invocation.equals(null));
43        assertFalse(invocation.equals(""));
44        assertTrue(invocation.equals(equal));
45        assertFalse(invocation.equals(nonEqual));
46        assertTrue(invocation.equals(withNewStringInstance));
47    }
48
49    @Test
50    public void shouldEqualToNotConsiderSequenceNumber() {
51        Invocation equal = new InvocationBuilder().args(" ").mock("mock").seq(2).toInvocation();
52
53        assertTrue(invocation.equals(equal));
54        assertTrue(invocation.getSequenceNumber() != equal.getSequenceNumber());
55    }
56
57    @Test
58    public void shouldBeACitizenOfHashes() {
59        Map<Invocation, String> map = new HashMap<Invocation, String>();
60        map.put(invocation, "one");
61        assertEquals("one", map.get(invocation));
62    }
63
64    @Test
65    public void shouldPrintMethodName() {
66        invocation = new InvocationBuilder().toInvocation();
67        assertEquals("iMethods.simpleMethod();", invocation.toString());
68    }
69
70    @Test
71    public void shouldPrintMethodArgs() {
72        invocation = new InvocationBuilder().args("foo").toInvocation();
73        Assertions.assertThat(invocation.toString()).endsWith("simpleMethod(\"foo\");");
74    }
75
76    @Test
77    public void shouldPrintMethodIntegerArgAndString() {
78        invocation = new InvocationBuilder().args("foo", 1).toInvocation();
79        Assertions.assertThat(invocation.toString()).endsWith("simpleMethod(\"foo\", 1);");
80    }
81
82    @Test
83    public void shouldPrintNull() {
84        invocation = new InvocationBuilder().args((String) null).toInvocation();
85        Assertions.assertThat(invocation.toString()).endsWith("simpleMethod(null);");
86    }
87
88    @Test
89    public void shouldPrintArray() {
90        invocation = new InvocationBuilder().method("oneArray").args(new int[] { 1, 2, 3 }).toInvocation();
91        Assertions.assertThat(invocation.toString()).endsWith("oneArray([1, 2, 3]);");
92    }
93
94    @Test
95    public void shouldPrintNullIfArrayIsNull() throws Exception {
96        Method m = IMethods.class.getMethod("oneArray", Object[].class);
97        invocation = new InvocationBuilder().method(m).args((Object) null).toInvocation();
98        Assertions.assertThat(invocation.toString()).endsWith("oneArray(null);");
99    }
100
101    @Test
102    public void shouldPrintArgumentsInMultilinesWhenGetsTooBig() {
103        invocation = new InvocationBuilder().args("veeeeery long string that makes it ugly in one line", 1).toInvocation();
104        Assertions.assertThat(invocation.toString()).endsWith(
105                "simpleMethod(" +
106                        "\n" +
107                        "    \"veeeeery long string that makes it ugly in one line\"," +
108                        "\n" +
109                        "    1" +
110                        "\n" +
111                        ");");
112    }
113
114    @Test
115    public void shouldTransformArgumentsToMatchers() throws Exception {
116        Invocation i = new InvocationBuilder().args("foo", new String[]{"bar"}).toInvocation();
117        List matchers = ArgumentsProcessor.argumentsToMatchers(i.getArguments());
118
119        assertEquals(2, matchers.size());
120        assertEquals(Equals.class, matchers.get(0).getClass());
121        assertEquals(ArrayEquals.class, matchers.get(1).getClass());
122    }
123
124    class Foo {
125        public String bark() {
126            return "woof";
127        }
128    }
129
130    @Test
131    public void shouldBeAbleToCallRealMethod() throws Throwable {
132        //when
133        Invocation invocation = invocationOf(Foo.class, "bark", new RealMethod() {
134            public Object invoke(Object target, Object[] arguments) throws Throwable {
135                return new Foo().bark();
136            }});
137        //then
138        assertEquals("woof", invocation.callRealMethod());
139    }
140
141    @Test
142    public void shouldScreamWhenCallingRealMethodOnInterface() throws Throwable {
143        //given
144        Invocation invocationOnInterface = new InvocationBuilder().toInvocation();
145
146        try {
147            //when
148            invocationOnInterface.callRealMethod();
149            //then
150            fail();
151        } catch(MockitoException e) {}
152    }
153
154    @Test
155    public void shouldReturnCastedArgumentAt(){
156        //given
157        int argument = 42;
158        Invocation invocationOnInterface = new InvocationBuilder().method("twoArgumentMethod").
159            argTypes(int.class, int.class).args(1, argument).toInvocation();
160
161        //when
162        int secondArgument = (Integer) invocationOnInterface.getArgument(1);
163
164        //then
165        assertTrue(secondArgument == argument);
166    }
167}
168