View Javadoc
1   /*
2    * Copyright (c) 2006 JMockit developers
3    * This file is subject to the terms of the MIT license (see LICENSE.txt).
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         // Do not proceed:
124         assertNull(mocked.anotherMethodToBeMocked(null, false, null));
125 
126         // Do proceed:
127         List<Integer> values = new ArrayList<>();
128         assertEquals("TEST[45]", mocked.anotherMethodToBeMocked("test", true, values));
129 
130         // Do not proceed again:
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 }