• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2018 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.internal.runners;
6 
7 import org.junit.runner.Description;
8 import org.junit.runner.manipulation.Filter;
9 import org.junit.runner.manipulation.NoTestsRemainException;
10 import org.junit.runner.notification.Failure;
11 import org.junit.runner.notification.RunListener;
12 import org.junit.runner.notification.RunNotifier;
13 import org.junit.runners.BlockJUnit4ClassRunner;
14 import org.junit.runners.model.FrameworkMethod;
15 import org.junit.runners.model.InitializationError;
16 import org.junit.runners.model.Statement;
17 import org.mockito.Mockito;
18 import org.mockito.MockitoAnnotations;
19 import org.mockito.internal.junit.DefaultTestFinishedEvent;
20 import org.mockito.internal.junit.MockitoTestListener;
21 import org.mockito.internal.util.Supplier;
22 
23 public class DefaultInternalRunner implements InternalRunner {
24 
25     private final BlockJUnit4ClassRunner runner;
26 
DefaultInternalRunner(Class<?> testClass, final Supplier<MockitoTestListener> listenerSupplier)27     public DefaultInternalRunner(Class<?> testClass, final Supplier<MockitoTestListener> listenerSupplier) throws InitializationError {
28         runner = new BlockJUnit4ClassRunner(testClass) {
29 
30             public Object target;
31             private MockitoTestListener mockitoTestListener;
32 
33             protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) {
34                 this.target = target;
35                 // get new test listener and add it to the framework
36                 mockitoTestListener = listenerSupplier.get();
37                 Mockito.framework().addListener(mockitoTestListener);
38                 // init annotated mocks before tests
39                 MockitoAnnotations.initMocks(target);
40                 return super.withBefores(method, target, statement);
41             }
42 
43             public void run(final RunNotifier notifier) {
44                 RunListener listener = new RunListener() {
45                     private boolean started;
46                     Throwable failure;
47 
48                     @Override
49                     public void testStarted(Description description) throws Exception {
50                         started = true;
51                     }
52 
53                     @Override
54                     public void testFailure(Failure failure) throws Exception {
55                         this.failure = failure.getException();
56                         // If the test fails during the setup, `testFinished` is never invoked
57                         // Therefore, if we have not started, cleanup the testlistener
58                         if (!started && mockitoTestListener != null) {
59                             Mockito.framework().removeListener(mockitoTestListener);
60                         }
61                     }
62 
63                     @Override
64                     public void testFinished(Description description) throws Exception {
65                         try {
66                             if (mockitoTestListener != null) {
67                                 Mockito.framework().removeListener(mockitoTestListener);
68                                 mockitoTestListener.testFinished(new DefaultTestFinishedEvent(target, description.getMethodName(), failure));
69                             }
70                             Mockito.validateMockitoUsage();
71                         } catch (Throwable t) {
72                             //In order to produce clean exception to the user we need to fire test failure with the right description
73                             //Otherwise JUnit framework will report failure with some generic test name
74                             notifier.fireTestFailure(new Failure(description, t));
75                         }
76                     }
77                 };
78                 notifier.addListener(listener);
79                 super.run(notifier);
80             }
81         };
82     }
83 
run(final RunNotifier notifier)84     public void run(final RunNotifier notifier) {
85         runner.run(notifier);
86     }
87 
getDescription()88     public Description getDescription() {
89         return runner.getDescription();
90     }
91 
filter(Filter filter)92     public void filter(Filter filter) throws NoTestsRemainException {
93         runner.filter(filter);
94     }
95 }
96