1 package mockit;
2
3 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4 import static org.junit.jupiter.api.Assertions.assertEquals;
5 import static org.junit.jupiter.api.Assertions.assertFalse;
6 import static org.junit.jupiter.api.Assertions.assertNotNull;
7 import static org.junit.jupiter.api.Assertions.assertSame;
8 import static org.junit.jupiter.api.Assertions.assertTrue;
9 import static org.junit.jupiter.api.Assertions.fail;
10
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.nio.ByteBuffer;
14 import java.util.Arrays;
15 import java.util.Date;
16 import java.util.LinkedList;
17 import java.util.Queue;
18
19 import org.junit.jupiter.api.Disabled;
20 import org.junit.jupiter.api.Test;
21 import org.junit.runner.RunWith;
22 import org.junit.runners.BlockJUnit4ClassRunner;
23
24
25
26
27 final class InstanceSpecificMockingTest {
28
29
30
31
32 static class Collaborator {
33
34
35 protected final int value;
36
37
38
39
40 Collaborator() {
41 value = -1;
42 }
43
44
45
46
47
48
49
50 Collaborator(int value) {
51 this.value = value;
52 }
53
54
55
56
57
58
59 int getValue() {
60 return value;
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74
75 @SuppressWarnings("unused")
76 final boolean simpleOperation(int a, String b, Date c) {
77 return true;
78 }
79
80
81
82
83
84
85
86
87
88 @SuppressWarnings("unused")
89 static void doSomething(boolean b, String s) {
90 throw new IllegalStateException();
91 }
92 }
93
94
95 final Collaborator previousInstance = new Collaborator();
96
97
98 @Injectable
99 Collaborator mock;
100
101
102
103
104 @Test
105 void exerciseInjectedInstanceDuringReplayOnly() {
106 assertThatPreviouslyCreatedInstanceIsNotMocked();
107
108 assertEquals(0, mock.value);
109 assertEquals(0, mock.getValue());
110 assertFalse(mock.simpleOperation(1, "test", null));
111
112 assertThatNewlyCreatedInstanceIsNotMocked();
113 }
114
115
116
117
118 void assertThatPreviouslyCreatedInstanceIsNotMocked() {
119 assertEquals(-1, previousInstance.value);
120 assertEquals(-1, previousInstance.getValue());
121 assertTrue(previousInstance.simpleOperation(1, "test", null));
122 }
123
124
125
126
127 void assertThatNewlyCreatedInstanceIsNotMocked() {
128 Collaborator newInstance = new Collaborator();
129 assertEquals(-1, newInstance.value);
130 assertEquals(-1, newInstance.getValue());
131 assertTrue(newInstance.simpleOperation(1, "test", null));
132 }
133
134
135
136
137 @Test
138 void mockSpecificInstance() {
139 new Expectations() {
140 {
141 mock.simpleOperation(1, "", null);
142 result = false;
143 mock.getValue();
144 result = 123;
145 times = 1;
146 }
147 };
148
149 assertFalse(mock.simpleOperation(1, "", null));
150 assertEquals(123, mock.getValue());
151 assertThatPreviouslyCreatedInstanceIsNotMocked();
152 assertThatNewlyCreatedInstanceIsNotMocked();
153
154 try {
155 Collaborator.doSomething(false, null);
156 fail();
157 } catch (IllegalStateException ignore) {
158 }
159 }
160
161
162
163
164
165
166
167 @Test
168 void useASecondMockInstanceOfTheSameType(@Injectable final Collaborator mock2) {
169 assertThatPreviouslyCreatedInstanceIsNotMocked();
170
171 new Expectations() {
172 {
173 mock2.getValue();
174 result = 2;
175 mock.getValue();
176 returns(1, 3);
177 }
178 };
179
180 assertEquals(1, mock.getValue());
181 assertEquals(2, mock2.getValue());
182 assertEquals(3, mock.getValue());
183 assertEquals(2, mock2.getValue());
184 assertEquals(3, mock.getValue());
185
186 assertThatPreviouslyCreatedInstanceIsNotMocked();
187 assertThatNewlyCreatedInstanceIsNotMocked();
188 }
189
190
191
192
193
194
195
196
197
198 @Test
199 void allowInjectableMockOfInterfaceType(@Injectable final Runnable runnable) {
200 runnable.run();
201 runnable.run();
202
203 new Verifications() {
204 {
205 runnable.run();
206 minTimes = 1;
207 maxTimes = 2;
208 }
209 };
210 }
211
212
213
214
215
216
217
218 @Test
219 void allowInjectableMockOfAnnotationType(@Injectable final RunWith runWith) {
220 new Expectations() {
221 {
222 runWith.value();
223 result = BlockJUnit4ClassRunner.class;
224 }
225 };
226
227 assertSame(BlockJUnit4ClassRunner.class, runWith.value());
228 }
229
230
231
232
233
234
235
236
237
238
239 @Disabled
240 @Test
241 void mockByteBufferAsInjectable(@Injectable final ByteBuffer buf) {
242 ByteBuffer realBuf = ByteBuffer.allocateDirect(10);
243 assertNotNull(realBuf);
244 assertEquals(10, realBuf.capacity());
245
246 new Expectations() {
247 {
248 buf.isDirect();
249 result = true;
250
251
252 buf.put("Test".getBytes());
253 times = 1;
254 }
255 };
256
257 assertTrue(buf.isDirect());
258 buf.put("Test".getBytes());
259 }
260
261
262
263
264
265
266
267
268 @Disabled
269 @Test
270 void mockByteBufferRegularly(@Mocked ByteBuffer mockBuffer) {
271 ByteBuffer buffer = ByteBuffer.allocateDirect(10);
272
273 assertSame(mockBuffer, buffer);
274
275 new Verifications() {
276 {
277 ByteBuffer.allocateDirect(anyInt);
278 }
279 };
280 }
281
282
283
284
285
286
287
288
289 @Disabled
290 @Test
291 void mockByteBufferAsCascading(@Mocked ByteBuffer unused) {
292 ByteBuffer cascadedBuf = ByteBuffer.allocateDirect(10);
293 assertNotNull(cascadedBuf);
294 assertEquals(0, cascadedBuf.capacity());
295 }
296
297
298
299
300 static class BufferFactory {
301
302
303
304
305
306 ByteBuffer createBuffer() {
307 return null;
308 }
309 }
310
311
312
313
314
315
316
317
318 @Disabled
319 @Test
320 void mockByteBufferAsCascadedMock(@Mocked BufferFactory cascadingMock) {
321 ByteBuffer realBuf1 = ByteBuffer.allocateDirect(10);
322 assertEquals(10, realBuf1.capacity());
323
324 ByteBuffer cascadedBuf = cascadingMock.createBuffer();
325 assertEquals(0, cascadedBuf.capacity());
326
327 ByteBuffer realBuf2 = ByteBuffer.allocateDirect(20);
328 assertEquals(20, realBuf2.capacity());
329 }
330
331
332
333
334
335
336 public static final class ConcatenatingInputStream extends InputStream {
337
338
339 private final Queue<InputStream> sequentialInputs;
340
341
342 private InputStream currentInput;
343
344
345
346
347
348
349
350 public ConcatenatingInputStream(InputStream... sequentialInputs) {
351 this.sequentialInputs = new LinkedList<>(Arrays.asList(sequentialInputs));
352 currentInput = this.sequentialInputs.poll();
353 }
354
355 @Override
356 public int read() throws IOException {
357 if (currentInput == null) {
358 return -1;
359 }
360
361 int nextByte = currentInput.read();
362
363 if (nextByte >= 0) {
364 return nextByte;
365 }
366
367 currentInput = sequentialInputs.poll();
368
369 return read();
370 }
371 }
372
373
374
375
376
377
378
379
380
381
382
383
384 @Test
385 void concatenateInputStreams(@Injectable final InputStream input1, @Injectable final InputStream input2)
386 throws Exception {
387 new Expectations() {
388 {
389 input1.read();
390 returns(1, 2, -1);
391 input2.read();
392 returns(3, -1);
393 }
394 };
395
396 InputStream concatenatedInput = new ConcatenatingInputStream(input1, input2);
397 byte[] buf = new byte[3];
398 concatenatedInput.read(buf);
399 concatenatedInput.close();
400
401 byte[] expectedBytes = { 1, 2, 3 };
402 assertArrayEquals(expectedBytes, buf);
403 }
404 }