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.integration.junit4;
6   
7   import edu.umd.cs.findbugs.annotations.NonNull;
8   import edu.umd.cs.findbugs.annotations.Nullable;
9   
10  import java.lang.annotation.Annotation;
11  import java.util.List;
12  
13  import mockit.Expectations;
14  import mockit.Invocation;
15  import mockit.Mock;
16  import mockit.MockUp;
17  import mockit.Tested;
18  import mockit.internal.faking.FakeInvocation;
19  import mockit.internal.util.StackTrace;
20  
21  import org.junit.runners.model.FrameworkMethod;
22  
23  /**
24   * Startup fake that modifies the JUnit 4.5+ test runner so that it calls back to JMockit immediately after every test
25   * executes. When that happens, JMockit will assert any expectations recorded during the test in {@link Expectations}
26   * subclasses.
27   * <p>
28   * This class is not supposed to be accessed from user code. JMockit will automatically load it at startup.
29   */
30  public final class FakeFrameworkMethod extends MockUp<FrameworkMethod> {
31      @NonNull
32      private final JUnit4TestRunnerDecorator decorator = new JUnit4TestRunnerDecorator();
33  
34      @Nullable
35      @Mock
36      public Object invokeExplosively(@NonNull Invocation invocation, Object target, Object... params) throws Throwable {
37          return decorator.invokeExplosively((FakeInvocation) invocation, target, params);
38      }
39  
40      @Mock
41      public static void validatePublicVoidNoArg(@NonNull Invocation invocation, boolean isStatic,
42              List<Throwable> errors) {
43          FrameworkMethod it = invocation.getInvokedInstance();
44          assert it != null;
45  
46          int previousErrorCount = errors.size();
47  
48          if (!isStatic && eachParameterContainsAKnownAnnotation(it.getMethod().getParameterAnnotations())) {
49              it.validatePublicVoid(false, errors);
50          } else {
51              ((FakeInvocation) invocation).prepareToProceedFromNonRecursiveMock();
52              it.validatePublicVoidNoArg(isStatic, errors);
53          }
54  
55          int errorCount = errors.size();
56  
57          for (int i = previousErrorCount; i < errorCount; i++) {
58              Throwable errorAdded = errors.get(i);
59              StackTrace.filterStackTrace(errorAdded);
60          }
61      }
62  
63      private static boolean eachParameterContainsAKnownAnnotation(
64              @NonNull Annotation[][] parametersAndTheirAnnotations) {
65          if (parametersAndTheirAnnotations.length == 0) {
66              return false;
67          }
68  
69          for (Annotation[] parameterAnnotations : parametersAndTheirAnnotations) {
70              if (!containsAKnownAnnotation(parameterAnnotations)) {
71                  return false;
72              }
73          }
74  
75          return true;
76      }
77  
78      private static boolean containsAKnownAnnotation(@NonNull Annotation[] parameterAnnotations) {
79          if (parameterAnnotations.length == 0) {
80              return false;
81          }
82  
83          for (Annotation parameterAnnotation : parameterAnnotations) {
84              Class<? extends Annotation> annotationType = parameterAnnotation.annotationType();
85              String annotationTypeName = annotationType.getName();
86  
87              if ("mockit.Tested mockit.Mocked mockit.Injectable mockit.Capturing".contains(annotationTypeName)
88                      || annotationType.isAnnotationPresent(Tested.class)) {
89                  return true;
90              }
91          }
92  
93          return false;
94      }
95  }