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