/
AbstractByteBuddyMockMakerTest.java
234 lines (187 loc) · 8 KB
/
AbstractByteBuddyMockMakerTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
* Copyright (c) 2017 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.creation.bytebuddy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockitoutil.ClassLoaders.coverageTool;
import java.io.Serializable;
import java.util.List;
import net.bytebuddy.ByteBuddy;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.internal.creation.MockSettingsImpl;
import org.mockito.internal.handler.MockHandlerImpl;
import org.mockito.internal.stubbing.answers.CallsRealMethods;
import org.mockito.invocation.Invocation;
import org.mockito.invocation.InvocationContainer;
import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.SerializableMode;
import org.mockito.plugins.MockMaker;
import org.mockito.stubbing.Answer;
import org.mockitoutil.ClassLoaders;
import org.mockitoutil.SimpleSerializationUtil;
import org.objenesis.ObjenesisStd;
public abstract class AbstractByteBuddyMockMakerTest<MM extends MockMaker> {
protected final MM mockMaker;
public AbstractByteBuddyMockMakerTest(MM mockMaker) {
this.mockMaker = mockMaker;
}
protected abstract Class<?> mockTypeOf(Class<?> type);
@Test
public void should_create_mock_from_interface() throws Exception {
SomeInterface proxy =
mockMaker.createMock(settingsFor(SomeInterface.class), dummyHandler());
Class<?> superClass = proxy.getClass().getSuperclass();
assertThat(superClass).isEqualTo(Object.class);
}
@Test
public void should_create_mock_from_class() throws Exception {
ClassWithoutConstructor proxy =
mockMaker.createMock(settingsFor(ClassWithoutConstructor.class), dummyHandler());
Class<?> superClass = mockTypeOf(proxy.getClass());
assertThat(superClass).isEqualTo(ClassWithoutConstructor.class);
}
@Test
public void should_create_mock_from_class_even_when_constructor_is_dodgy() throws Exception {
try {
new ClassWithDodgyConstructor();
fail();
} catch (Exception expected) {
}
ClassWithDodgyConstructor mock =
mockMaker.createMock(settingsFor(ClassWithDodgyConstructor.class), dummyHandler());
assertThat(mock).isNotNull();
}
@Test
public void should_mocks_have_different_interceptors() throws Exception {
SomeClass mockOne = mockMaker.createMock(settingsFor(SomeClass.class), dummyHandler());
SomeClass mockTwo = mockMaker.createMock(settingsFor(SomeClass.class), dummyHandler());
MockHandler handlerOne = mockMaker.getHandler(mockOne);
MockHandler handlerTwo = mockMaker.getHandler(mockTwo);
assertThat(handlerOne).isNotSameAs(handlerTwo);
}
@Test
public void should_use_ancillary_Types() {
SomeClass mock =
mockMaker.createMock(
settingsFor(SomeClass.class, SomeInterface.class), dummyHandler());
assertThat(mock).isInstanceOf(SomeInterface.class);
}
@Test
public void should_create_class_by_constructor() {
OtherClass mock =
mockMaker.createMock(settingsWithConstructorFor(OtherClass.class), dummyHandler());
assertThat(mock).isNotNull();
}
@Test
public void should_allow_serialization() throws Exception {
SerializableClass proxy =
mockMaker.createMock(
serializableSettingsFor(SerializableClass.class, SerializableMode.BASIC),
dummyHandler());
SerializableClass serialized = SimpleSerializationUtil.serializeAndBack(proxy);
assertThat(serialized).isNotNull();
MockHandler handlerOne = mockMaker.getHandler(proxy);
MockHandler handlerTwo = mockMaker.getHandler(serialized);
assertThat(handlerOne).isNotSameAs(handlerTwo);
}
@Test
public void should_create_mock_from_class_with_super_call_to_final_method() throws Exception {
MockCreationSettings<CallingSuperMethodClass> settings =
settingsWithSuperCall(CallingSuperMethodClass.class);
SampleClass proxy =
mockMaker.createMock(
settings, new MockHandlerImpl<CallingSuperMethodClass>(settings));
assertThat(proxy.foo()).isEqualTo("foo");
}
@Test
public void should_reset_mock_and_set_new_handler() throws Throwable {
MockCreationSettings<SampleClass> settings = settingsWithSuperCall(SampleClass.class);
SampleClass proxy =
mockMaker.createMock(settings, new MockHandlerImpl<SampleClass>(settings));
MockHandler handler = new MockHandlerImpl<SampleClass>(settings);
mockMaker.resetMock(proxy, handler, settings);
assertThat(mockMaker.getHandler(proxy)).isSameAs(handler);
}
class SomeClass {}
interface SomeInterface {}
static class OtherClass {}
static class SerializableClass implements Serializable {}
private class ClassWithoutConstructor {}
private class ClassWithDodgyConstructor {
public ClassWithDodgyConstructor() {
throw new RuntimeException();
}
}
@Test
public void instantiate_fine_when_objenesis_on_the_classpath() throws Exception {
// given
ClassLoader classpath_with_objenesis =
ClassLoaders.excludingClassLoader()
.withCodeSourceUrlOf(Mockito.class, ByteBuddy.class, ObjenesisStd.class)
.withCodeSourceUrlOf(coverageTool())
.build();
Class<?> mock_maker_class_loaded_fine_until =
Class.forName(
"org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker",
true,
classpath_with_objenesis);
// when
mock_maker_class_loaded_fine_until.getConstructor().newInstance();
// then everything went fine
}
private static <T> MockCreationSettings<T> settingsFor(
Class<T> type, Class<?>... extraInterfaces) {
MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>();
mockSettings.setTypeToMock(type);
if (extraInterfaces.length > 0) mockSettings.extraInterfaces(extraInterfaces);
return mockSettings;
}
private static <T> MockCreationSettings<T> serializableSettingsFor(
Class<T> type, SerializableMode serializableMode) {
MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>();
mockSettings.serializable(serializableMode);
mockSettings.setTypeToMock(type);
return mockSettings;
}
private static <T> MockCreationSettings<T> settingsWithConstructorFor(Class<T> type) {
MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>();
mockSettings.setTypeToMock(type);
return mockSettings;
}
private static <T> MockCreationSettings<T> settingsWithSuperCall(Class<T> type) {
MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>();
mockSettings.setTypeToMock(type);
mockSettings.defaultAnswer(new CallsRealMethods());
return mockSettings;
}
protected static MockHandler dummyHandler() {
return new DummyMockHandler();
}
private static class DummyMockHandler implements MockHandler<Object> {
public Object handle(Invocation invocation) throws Throwable {
return null;
}
public MockCreationSettings<Object> getMockSettings() {
return null;
}
public InvocationContainer getInvocationContainer() {
return null;
}
public void setAnswersForStubbing(List<Answer<?>> list) {}
}
private static class SampleClass {
public String foo() {
return "foo";
}
}
private static class CallingSuperMethodClass extends SampleClass {
@Override
public String foo() {
return super.foo();
}
}
}