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}@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 @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 @Mock annotation in javadoc for {@link MockitoAnnotations} 57 * <pre class="code"><code class="java"> 58 * <b>@RunWith(MockitoJUnitRunner.StrictStubs.class)</b> 59 * public class ExampleTest { 60 * 61 * @Mock 62 * private List list; 63 * 64 * @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>@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>@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