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.mockito.exceptions.Reporter;
9import org.mockito.internal.debugging.LocationImpl;
10import org.mockito.internal.exceptions.VerificationAwareInvocation;
11import org.mockito.internal.invocation.realmethod.RealMethod;
12import org.mockito.internal.reporting.PrintSettings;
13import org.mockito.invocation.*;
14
15import java.lang.reflect.Method;
16import java.util.Arrays;
17
18/**
19 * Method call on a mock object.
20 * <p>
21 * Contains sequence number which should be globally unique and is used for
22 * verification in order.
23 * <p>
24 * Contains stack trace of invocation
25 */
26@SuppressWarnings("unchecked")
27public class InvocationImpl implements Invocation, VerificationAwareInvocation {
28
29    private static final long serialVersionUID = 8240069639250980199L;
30    private final int sequenceNumber;
31    private final Object mock;
32    private final MockitoMethod method;
33    private final Object[] arguments;
34    private final Object[] rawArguments;
35
36    private final Location location;
37    private boolean verified;
38    private boolean isIgnoredForVerification;
39
40    final RealMethod realMethod;
41    private StubInfo stubInfo;
42
43    public InvocationImpl(Object mock, MockitoMethod mockitoMethod, Object[] args, int sequenceNumber, RealMethod realMethod) {
44        this.method = mockitoMethod;
45        this.mock = mock;
46        this.realMethod = realMethod;
47        this.arguments = ArgumentsProcessor.expandVarArgs(mockitoMethod.isVarArgs(), args);
48        this.rawArguments = args;
49        this.sequenceNumber = sequenceNumber;
50        this.location = new LocationImpl();
51    }
52
53    public Object getMock() {
54        return mock;
55    }
56
57    public Method getMethod() {
58        return method.getJavaMethod();
59    }
60
61    public Object[] getArguments() {
62        return arguments;
63    }
64
65    public boolean isVerified() {
66        return verified || isIgnoredForVerification;
67    }
68
69    public int getSequenceNumber() {
70        return sequenceNumber;
71    }
72
73    public boolean equals(Object o) {
74        if (o == null || !o.getClass().equals(this.getClass())) {
75            return false;
76        }
77
78        InvocationImpl other = (InvocationImpl) o;
79
80        return this.mock.equals(other.mock) && this.method.equals(other.method) && this.equalArguments(other.arguments);
81    }
82
83    private boolean equalArguments(Object[] arguments) {
84        return Arrays.equals(arguments, this.arguments);
85    }
86
87    @Override
88    public int hashCode() {
89        return 1;
90    }
91
92    public String toString() {
93        return new PrintSettings().print(ArgumentsProcessor.argumentsToMatchers(getArguments()), this);
94    }
95
96    public Location getLocation() {
97        return location;
98    }
99
100    public Object[] getRawArguments() {
101        return this.rawArguments;
102    }
103
104    public Object callRealMethod() throws Throwable {
105        if (this.getMethod().getDeclaringClass().isInterface()) {
106            new Reporter().cannotCallRealMethodOnInterface();
107        }
108        return realMethod.invoke(mock, rawArguments);
109    }
110
111    public void markVerified() {
112        this.verified = true;
113    }
114
115    public StubInfo stubInfo() {
116        return stubInfo;
117    }
118
119    public void markStubbed(StubInfo stubInfo) {
120        this.stubInfo = stubInfo;
121    }
122
123    public boolean isIgnoredForVerification() {
124        return isIgnoredForVerification;
125    }
126
127    public void ignoreForVerification() {
128        isIgnoredForVerification = true;
129    }
130}