1
2
3
4
5
6 package mockit;
7
8 import static org.junit.jupiter.api.Assertions.assertEquals;
9 import static org.junit.jupiter.api.Assertions.assertNotNull;
10 import static org.junit.jupiter.api.Assertions.assertNull;
11 import static org.junit.jupiter.api.Assertions.assertThrows;
12 import static org.junit.jupiter.api.Assertions.assertTrue;
13 import static org.junit.jupiter.api.Assertions.fail;
14
15 import java.io.File;
16 import java.io.FileNotFoundException;
17 import java.io.IOException;
18 import java.nio.file.Path;
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.junit.jupiter.api.Test;
23
24 public final class MockInvocationProceedTest {
25
26 public static class BaseClassToBeMocked {
27 protected String name;
28
29 public final int baseMethod(int i) {
30 return i + 1;
31 }
32
33 protected int methodToBeMocked(int i) throws IOException {
34 return i;
35 }
36 }
37
38 public static class ClassToBeMocked extends BaseClassToBeMocked {
39 public ClassToBeMocked() {
40 name = "";
41 }
42
43 public ClassToBeMocked(String name) {
44 this.name = name;
45 }
46
47 public boolean methodToBeMocked() {
48 return true;
49 }
50
51 protected int methodToBeMocked(int i, Object... args) {
52 int result = i;
53
54 for (Object arg : args) {
55 if (arg != null)
56 result++;
57 }
58
59 return result;
60 }
61
62 public String anotherMethodToBeMocked(String s, boolean b, List<Integer> ints) {
63 return (b ? s.toUpperCase() : s.toLowerCase()) + ints;
64 }
65
66 public static boolean staticMethodToBeMocked() throws FileNotFoundException {
67 throw new FileNotFoundException();
68 }
69
70 protected static native void nativeMethod();
71 }
72
73 @Test
74 public void proceedFromMockMethodWithoutParameters() {
75 new MockUp<ClassToBeMocked>() {
76 @Mock
77 boolean methodToBeMocked(Invocation inv) {
78 return inv.proceed();
79 }
80 };
81
82 assertTrue(new ClassToBeMocked().methodToBeMocked());
83 }
84
85 @Test
86 public void proceedFromMockMethodWithParameters() throws Exception {
87 new MockUp<ClassToBeMocked>() {
88 @Mock
89 int methodToBeMocked(Invocation inv, int i) {
90 Integer j = inv.proceed();
91 return j + 1;
92 }
93
94 @Mock
95 private int methodToBeMocked(Invocation inv, int i, Object... args) {
96 args[2] = "mock";
97 return inv.<Integer> proceed();
98 }
99 };
100
101 ClassToBeMocked mocked = new ClassToBeMocked();
102
103 assertEquals(124, mocked.methodToBeMocked(123));
104 assertEquals(-8, mocked.methodToBeMocked(-9));
105 assertEquals(7, mocked.methodToBeMocked(3, "Test", new Object(), null, 45));
106 }
107
108 @Test
109 public void proceedConditionallyFromMockMethod() throws Exception {
110 new MockUp<ClassToBeMocked>() {
111 @Mock
112 String anotherMethodToBeMocked(Invocation inv, String s, boolean b, List<Number> ints) {
113 if (!b) {
114 return s;
115 }
116
117 ints.add(45);
118 return inv.proceed();
119 }
120 };
121
122 ClassToBeMocked mocked = new ClassToBeMocked();
123
124
125 assertNull(mocked.anotherMethodToBeMocked(null, false, null));
126
127
128 List<Integer> values = new ArrayList<>();
129 assertEquals("TEST[45]", mocked.anotherMethodToBeMocked("test", true, values));
130
131
132 assertEquals("No proceed", mocked.anotherMethodToBeMocked("No proceed", false, null));
133 }
134
135 @Test
136 public void proceedFromMockMethodWhichThrowsCheckedException() throws Exception {
137 new MockUp<ClassToBeMocked>() {
138 @Mock
139 boolean staticMethodToBeMocked(Invocation inv) throws Exception {
140 if (inv.getInvocationIndex() == 0) {
141 return inv.<Boolean> proceed();
142 }
143
144 throw new InterruptedException("fake");
145 }
146 };
147
148 try {
149 ClassToBeMocked.staticMethodToBeMocked();
150 fail();
151 } catch (FileNotFoundException ignored) {
152 }
153
154 assertThrows(InterruptedException.class, () -> {
155 ClassToBeMocked.staticMethodToBeMocked();
156 });
157 }
158
159 @Test
160 public void cannotProceedFromMockMethodIntoNativeMethod() {
161 new MockUp<ClassToBeMocked>() {
162 @Mock
163 void nativeMethod(Invocation inv) {
164 inv.proceed();
165 fail("Should not get here");
166 }
167 };
168
169 Throwable throwable = assertThrows(UnsupportedOperationException.class, () -> {
170 ClassToBeMocked.nativeMethod();
171 });
172 assertEquals("Cannot proceed into real implementation of native method", throwable.getMessage());
173 }
174
175 @Test
176 public void proceedFromMockMethodIntoConstructor() {
177 new MockUp<ClassToBeMocked>() {
178 @Mock
179 void $init(Invocation inv) {
180 assertNotNull(inv.<ClassToBeMocked> getInvokedInstance());
181 inv.proceed();
182 }
183 };
184
185 ClassToBeMocked obj = new ClassToBeMocked();
186 assertEquals("", obj.name);
187 }
188
189 @Test
190 public void proceedConditionallyFromMockMethodIntoConstructor() {
191 new MockUp<ClassToBeMocked>() {
192 @Mock
193 void $init(Invocation inv, String name) {
194 assertNotNull(inv.getInvokedInstance());
195
196 if ("proceed".equals(name)) {
197 inv.proceed();
198 }
199 }
200 };
201
202 assertEquals("proceed", new ClassToBeMocked("proceed").name);
203 assertNull(new ClassToBeMocked("do not proceed").name);
204 }
205
206 @Test
207 public void proceedConditionallyFromMockMethodIntoJREConstructor() {
208 new MockUp<File>() {
209 @Mock
210 void $init(Invocation inv, String name) {
211 if ("proceed".equals(name)) {
212 inv.proceed();
213 }
214 }
215 };
216
217 assertEquals("proceed", Path.of("proceed").toFile().toString());
218 assertNull(Path.of("do not proceed").toFile().toString());
219 }
220
221 @Test
222 public void proceedFromMockMethodIntoMethodInheritedFromBaseClass() {
223 new MockUp<ClassToBeMocked>() {
224 @Mock
225 int baseMethod(Invocation inv, int i) {
226 return inv.proceed(i + 1);
227 }
228 };
229
230 assertEquals(3, new ClassToBeMocked().baseMethod(1));
231 }
232 }