1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.junit;
6 
7 import java.lang.reflect.InvocationTargetException;
8 import org.junit.runner.Description;
9 import org.junit.runner.Runner;
10 import org.junit.runner.manipulation.Filter;
11 import org.junit.runner.manipulation.Filterable;
12 import org.junit.runner.manipulation.NoTestsRemainException;
13 import org.junit.runner.notification.RunNotifier;
14 import org.mockito.Mock;
15 import org.mockito.Mockito;
16 import org.mockito.MockitoAnnotations;
17 import org.mockito.MockitoSession;
18 import org.mockito.exceptions.misusing.UnnecessaryStubbingException;
19 import org.mockito.internal.runners.RunnerFactory;
20 import org.mockito.internal.runners.InternalRunner;
21 import org.mockito.internal.runners.StrictRunner;
22 import org.mockito.quality.MockitoHint;
23 import org.mockito.quality.Strictness;
24 
25 
26 /**
27  * Mockito JUnit Runner keeps tests clean and improves debugging experience.
28  * Make sure to try out {@link MockitoJUnitRunner.StrictStubs} which automatically
29  * detects <strong>stubbing argument mismatches</strong> and is planned to be the default in Mockito v3.
30  * Runner is compatible with JUnit 4.4 and higher and adds following behavior:
31  * <ul>
32  *   <li>
33  *       (new since Mockito 2.1.0) Detects unused stubs in the test code.
34  *       See {@link UnnecessaryStubbingException}.
35  *       Similar to JUnit rules, the runner also reports stubbing argument mismatches as console warnings
36  *       (see {@link MockitoHint}).
37  *       To opt-out from this feature, use {@code}&#064;RunWith(MockitoJUnitRunner.Silent.class){@code}
38  *   <li>
39  *      Initializes mocks annotated with {@link Mock},
40  *      so that explicit usage of {@link MockitoAnnotations#initMocks(Object)} is not necessary.
41  *      Mocks are initialized before each test method.
42  *   <li>
43  *      Validates framework usage after each test method. See javadoc for {@link Mockito#validateMockitoUsage()}.
44  *   <li>
45  *      It is highly recommended to use {@link MockitoJUnitRunner.StrictStubs} variant of the runner.
46  *      It drives cleaner tests and improves debugging experience.
47  *      The only reason this feature is not turned on by default
48  *      is because it would have been an incompatible change
49  *      and Mockito strictly follows <a href="http://semver.org">semantic versioning</a>.
50  * </ul>
51  *
52  * Runner is completely optional - there are other ways you can get &#064;Mock working, for example by writing a base class.
53  * Explicitly validating framework usage is also optional because it is triggered automatically by Mockito every time you use the framework.
54  * See javadoc for {@link Mockito#validateMockitoUsage()}.
55  * <p>
56  * Read more about &#064;Mock annotation in javadoc for {@link MockitoAnnotations}
57  * <pre class="code"><code class="java">
58  * <b>&#064;RunWith(MockitoJUnitRunner.StrictStubs.class)</b>
59  * public class ExampleTest {
60  *
61  *     &#064;Mock
62  *     private List list;
63  *
64  *     &#064;Test
65  *     public void shouldDoSomething() {
66  *         list.add(100);
67  *     }
68  * }
69  * </code></pre>
70  *
71  * If you would like to take advantage of Mockito JUnit runner features
72  * but you cannot use the runner because, for example, you use TestNG, there is a solution!
73  * {@link MockitoSession} API is intended to offer cleaner tests and improved debuggability
74  * to users that cannot use Mockito's built-in JUnit support (runner or the rule).
75  */
76 public class MockitoJUnitRunner extends Runner implements Filterable {
77 
78     /**
79      * This Mockito JUnit Runner implementation *ignores*
80      * stubbing argument mismatches ({@link MockitoJUnitRunner.StrictStubs})
81      * and *does not detect* unused stubbings.
82      * The runner remains 'silent' even if incorrect stubbing is present.
83      * This was the behavior of Mockito JUnit runner in versions 1.x.
84      * Using this implementation of the runner is not recommended.
85      * Engineers should care for removing unused stubbings because they are dead code,
86      * they add unnecessary details, potentially making the test code harder to comprehend.
87      * If you have good reasons to use the silent runner, let us know at the mailing list
88      * or raise an issue in our issue tracker.
89      * The purpose of silent implementation is to satisfy edge/unanticipated use cases,
90      * and to offer users an opt-out.
91      * Mockito framework is opinionated to drive clean tests but it is not dogmatic.
92      * <p>
93      * See also {@link UnnecessaryStubbingException}.
94      * <p>
95      * Usage:
96      * <pre class="code"><code class="java">
97      * <b>&#064;RunWith(MockitoJUnitRunner.Silent.class)</b>
98      * public class ExampleTest {
99      *   // ...
100      * }
101      * </code></pre>
102      *
103      * @since 2.1.0
104      */
105     public static class Silent extends MockitoJUnitRunner {
Silent(Class<?> klass)106         public Silent(Class<?> klass) throws InvocationTargetException {
107             super(new RunnerFactory().create(klass));
108         }
109     }
110 
111     /**
112      * Detects unused stubs and reports them as failures. Default behavior in Mockito 2.x.
113      * To improve productivity and quality of tests please consider newer API, the {@link StrictStubs}.
114      * <p>
115      * For more information on detecting unusued stubs, see {@link UnnecessaryStubbingException}.
116      * For more information on stubbing argument mismatch warnings see {@link MockitoHint}.
117      *
118      * @since 2.1.0
119      */
120     public static class Strict extends MockitoJUnitRunner {
Strict(Class<?> klass)121         public Strict(Class<?> klass) throws InvocationTargetException {
122             super(new StrictRunner(new RunnerFactory().createStrict(klass), klass));
123         }
124     }
125 
126     /**
127      * Improves debugging tests, helps keeping the tests clean.
128      * Highly recommended to improve productivity and quality of tests.
129      * Planned default behavior for Mockito v3.
130      * Adds behavior equivalent to {@link Strictness#STRICT_STUBS}.
131      * <p>
132      * Usage:
133      * <pre class="code"><code class="java">
134      * <b>&#064;RunWith(MockitoJUnitRunner.StrictStubs.class)</b>
135      * public class ExampleTest {
136      *   // ...
137      * }
138      * </code></pre>
139      *
140      * @since 2.5.1
141      */
142     public static class StrictStubs extends MockitoJUnitRunner {
StrictStubs(Class<?> klass)143         public StrictStubs(Class<?> klass) throws InvocationTargetException {
144             super(new StrictRunner(new RunnerFactory().createStrictStubs(klass), klass));
145         }
146     }
147 
148     private final InternalRunner runner;
149 
MockitoJUnitRunner(Class<?> klass)150     public MockitoJUnitRunner(Class<?> klass) throws InvocationTargetException {
151         //by default, StrictRunner is used. We can change that potentially based on feedback from users
152         this(new StrictRunner(new RunnerFactory().createStrict(klass), klass));
153     }
154 
MockitoJUnitRunner(InternalRunner runner)155     MockitoJUnitRunner(InternalRunner runner) throws InvocationTargetException {
156         this.runner = runner;
157     }
158 
159     @Override
run(final RunNotifier notifier)160     public void run(final RunNotifier notifier) {
161         runner.run(notifier);
162     }
163 
164     @Override
getDescription()165     public Description getDescription() {
166         return runner.getDescription();
167     }
168 
filter(Filter filter)169     public void filter(Filter filter) throws NoTestsRemainException {
170         //filter is required because without it UnrootedTests show up in Eclipse
171         runner.filter(filter);
172     }
173 }
174