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