/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.junit;
import org.junit.runner.
Description;
import org.junit.runner.
Runner;
import org.junit.runner.manipulation.
Filter;
import org.junit.runner.manipulation.
Filterable;
import org.junit.runner.manipulation.
NoTestsRemainException;
import org.junit.runner.notification.
RunNotifier;
import org.mockito.
Mock;
import org.mockito.
Mockito;
import org.mockito.
MockitoAnnotations;
import org.mockito.
MockitoSession;
import org.mockito.exceptions.misusing.
UnnecessaryStubbingException;
import org.mockito.internal.runners.
InternalRunner;
import org.mockito.internal.runners.
RunnerFactory;
import org.mockito.internal.runners.
StrictRunner;
import org.mockito.quality.
MockitoHint;
import org.mockito.quality.
Strictness;
import java.lang.reflect.
InvocationTargetException;
/**
* Mockito JUnit Runner keeps tests clean and improves debugging experience.
* Make sure to try out {@link MockitoJUnitRunner.StrictStubs} which automatically
* detects <strong>stubbing argument mismatches</strong> and is planned to be the default in Mockito v3.
* Runner is compatible with JUnit 4.4 and higher and adds following behavior:
* <ul>
* <li>
* (new since Mockito 2.1.0) Detects unused stubs in the test code.
* See {@link UnnecessaryStubbingException}.
* Similar to JUnit rules, the runner also reports stubbing argument mismatches as console warnings
* (see {@link MockitoHint}).
* To opt-out from this feature, use {@code}@RunWith(MockitoJUnitRunner.Silent.class){@code}
* <li>
* Initializes mocks annotated with {@link Mock},
* so that explicit usage of {@link MockitoAnnotations#initMocks(Object)} is not necessary.
* Mocks are initialized before each test method.
* <li>
* Validates framework usage after each test method. See javadoc for {@link Mockito#validateMockitoUsage()}.
* <li>
* It is highly recommended to use {@link MockitoJUnitRunner.StrictStubs} variant of the runner.
* It drives cleaner tests and improves debugging experience.
* The only reason this feature is not turned on by default
* is because it would have been an incompatible change
* and Mockito strictly follows <a href="http://semver.org">semantic versioning</a>.
* </ul>
*
* Runner is completely optional - there are other ways you can get @Mock working, for example by writing a base class.
* Explicitly validating framework usage is also optional because it is triggered automatically by Mockito every time you use the framework.
* See javadoc for {@link Mockito#validateMockitoUsage()}.
* <p>
* Read more about @Mock annotation in javadoc for {@link MockitoAnnotations}
* <pre class="code"><code class="java">
* <b>@RunWith(MockitoJUnitRunner.StrictStubs.class)</b>
* public class ExampleTest {
*
* @Mock
* private List list;
*
* @Test
* public void shouldDoSomething() {
* list.add(100);
* }
* }
* </code></pre>
*
* If you would like to take advantage of Mockito JUnit runner features
* but you cannot use the runner because, for example, you use TestNG, there is a solution!
* {@link MockitoSession} API is intended to offer cleaner tests and improved debuggability
* to users that cannot use Mockito's built-in JUnit support (runner or the rule).
*/
public class
MockitoJUnitRunner extends
Runner implements
Filterable {
/**
* This Mockito JUnit Runner implementation *ignores*
* stubbing argument mismatches ({@link MockitoJUnitRunner.StrictStubs})
* and *does not detect* unused stubbings.
* The runner remains 'silent' even if incorrect stubbing is present.
* It is an equivalent of {@link Strictness#LENIENT}.
* This was the behavior of Mockito JUnit runner in versions 1.x.
* Using this implementation of the runner is not recommended.
* Engineers should care for removing unused stubbings because they are dead code,
* they add unnecessary details, potentially making the test code harder to comprehend.
* If you have good reasons to use the silent runner, let us know at the mailing list
* or raise an issue in our issue tracker.
* The purpose of silent implementation is to satisfy edge/unanticipated use cases,
* and to offer users an opt-out.
* Mockito framework is opinionated to drive clean tests but it is not dogmatic.
* <p>
* See also {@link UnnecessaryStubbingException}.
* <p>
* Usage:
* <pre class="code"><code class="java">
* <b>@RunWith(MockitoJUnitRunner.Silent.class)</b>
* public class ExampleTest {
* // ...
* }
* </code></pre>
*
* @since 2.1.0
*/
public static class
Silent extends
MockitoJUnitRunner {
public
Silent(
Class<?>
klass) throws
InvocationTargetException {
super(new
RunnerFactory().
create(
klass));
}
}
/**
* Detects unused stubs and reports them as failures. Default behavior in Mockito 2.x.
* To improve productivity and quality of tests please consider newer API, the {@link StrictStubs}.
* <p>
* For more information on detecting unusued stubs, see {@link UnnecessaryStubbingException}.
* For more information on stubbing argument mismatch warnings see {@link MockitoHint}.
*
* @since 2.1.0
*/
public static class
Strict extends
MockitoJUnitRunner {
public
Strict(
Class<?>
klass) throws
InvocationTargetException {
super(new
StrictRunner(new
RunnerFactory().
createStrict(
klass),
klass));
}
}
/**
* Improves debugging tests, helps keeping the tests clean.
* Highly recommended to improve productivity and quality of tests.
* Planned default behavior for Mockito v3.
* Adds behavior equivalent to {@link Strictness#STRICT_STUBS}.
* <p>
* Usage:
* <pre class="code"><code class="java">
* <b>@RunWith(MockitoJUnitRunner.StrictStubs.class)</b>
* public class ExampleTest {
* // ...
* }
* </code></pre>
*
* @since 2.5.1
*/
public static class
StrictStubs extends
MockitoJUnitRunner {
public
StrictStubs(
Class<?>
klass) throws
InvocationTargetException {
super(new
StrictRunner(new
RunnerFactory().
createStrictStubs(
klass),
klass));
}
}
private final
InternalRunner runner;
public
MockitoJUnitRunner(
Class<?>
klass) throws
InvocationTargetException {
//by default, StrictRunner is used. We can change that potentially based on feedback from users
this(new
StrictRunner(new
RunnerFactory().
createStrict(
klass),
klass));
}
MockitoJUnitRunner(
InternalRunner runner) throws
InvocationTargetException {
this.
runner =
runner;
}
@
Override
public void run(final
RunNotifier notifier) {
runner.
run(
notifier);
}
@
Override
public
Description getDescription() {
return
runner.
getDescription();
}
public void filter(
Filter filter) throws
NoTestsRemainException {
//filter is required because without it UnrootedTests show up in Eclipse
runner.
filter(
filter);
}
}