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