InvocationBuilder.java revision 2637d96c202372854a7c71466ddcc6e90fc4fc53
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 java.lang.reflect.Method;
9import java.util.LinkedList;
10import java.util.List;
11import org.mockito.Mockito;
12import org.mockito.internal.debugging.LocationImpl;
13import org.mockito.internal.invocation.realmethod.RealMethod;
14import org.mockito.internal.util.reflection.AccessibilityChanger;
15import org.mockito.invocation.Invocation;
16import org.mockito.invocation.Location;
17import org.mockitousage.IMethods;
18
19import static java.util.Arrays.asList;
20
21/**
22 * Build an invocation.
23 */
24@SuppressWarnings("unchecked")
25public class InvocationBuilder {
26
27    private String methodName = "simpleMethod";
28    private int sequenceNumber = 0;
29    private Object[] args = new Object[]{};
30    private Object mock = Mockito.mock(IMethods.class);
31    private Method method;
32    private boolean verified;
33    private List<Class<?>> argTypes;
34    private Location location;
35
36    /**
37     * Build the invocation
38     * <p>
39     * If the method was not specified, use IMethods methods.
40     *
41     * @return invocation
42     */
43    public Invocation toInvocation() {
44        if (method == null) {
45            if (argTypes == null) {
46                argTypes = new LinkedList<Class<?>>();
47                for (Object arg : args) {
48                    if (arg == null) {
49                        argTypes.add(Object.class);
50                    } else {
51                        argTypes.add(arg.getClass());
52                    }
53                }
54            }
55
56            try {
57                method = IMethods.class.getMethod(methodName, argTypes.toArray(new Class[argTypes.size()]));
58            } catch (Exception e) {
59                throw new RuntimeException("builder only creates invocations of IMethods interface", e);
60            }
61        }
62
63        Invocation i = new InvocationImpl(mock,
64                                          new SerializableMethod(method),
65                                          args,
66                                          sequenceNumber,
67                                          toDumbRealMethod(),
68                                          location == null ? new LocationImpl() : location);
69        if (verified) {
70            i.markVerified();
71        }
72        return i;
73    }
74
75    private RealMethod toDumbRealMethod() {
76        return new RealMethod() {
77            @Override
78            public Object invoke(Object target, Object[] arguments) throws Throwable {
79                AccessibilityChanger accessibilityChanger = new AccessibilityChanger();
80                try {
81                    accessibilityChanger.enableAccess(method);
82                    return method.invoke(target, arguments);
83                } finally {
84                    accessibilityChanger.safelyDisableAccess(method);
85                }
86
87            }
88        };
89    }
90
91    public InvocationBuilder method(String methodName) {
92        this.methodName = methodName;
93        return this;
94    }
95
96    public InvocationBuilder seq(int sequenceNumber) {
97        this.sequenceNumber = sequenceNumber;
98        return this;
99    }
100
101    public InvocationBuilder args(Object... args) {
102        this.args = args;
103        return this;
104    }
105
106    public InvocationBuilder arg(Object o) {
107        this.args = new Object[]{o};
108        return this;
109    }
110
111    public InvocationBuilder mock(Object mock) {
112        this.mock = mock;
113        return this;
114    }
115
116    public InvocationBuilder method(Method method) {
117        this.method = method;
118        return this;
119    }
120
121    public InvocationBuilder verified() {
122        this.verified = true;
123        return this;
124    }
125
126    public InvocationMatcher toInvocationMatcher() {
127        return new InvocationMatcher(toInvocation());
128    }
129
130    public InvocationBuilder simpleMethod() {
131        return this.method("simpleMethod");
132    }
133
134    public InvocationBuilder differentMethod() {
135        return this.method("differentMethod");
136    }
137
138    public InvocationBuilder argTypes(Class<?>... argTypes) {
139        this.argTypes = asList(argTypes);
140        return this;
141    }
142
143    public InvocationBuilder location(final String location) {
144        this.location = new Location() {
145            public String toString() {
146                return location;
147            }
148        };
149        return this;
150    }
151}
152