1 /* 2 * Copyright (c) 2017 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito; 6 7 import org.mockito.exceptions.misusing.PotentialStubbingProblem; 8 import org.mockito.exceptions.misusing.UnfinishedMockingSessionException; 9 import org.mockito.exceptions.misusing.UnnecessaryStubbingException; 10 import org.mockito.junit.MockitoJUnitRunner; 11 import org.mockito.junit.MockitoRule; 12 import org.mockito.listeners.MockitoListener; 13 import org.mockito.quality.MockitoHint; 14 import org.mockito.quality.Strictness; 15 import org.mockito.session.MockitoSessionBuilder; 16 17 /** 18 * {@code MockitoSession} is an optional, highly recommended feature 19 * that helps driving cleaner tests by eliminating boilerplate code and adding extra validation. 20 * If you already use {@link MockitoJUnitRunner} or {@link MockitoRule} 21 * *you don't need* {@code MockitoSession} because it is used by the runner/rule. 22 * <p> 23 * {@code MockitoSession} is a session of mocking, during which the user creates and uses Mockito mocks. 24 * Typically the session is an execution of a single test method. 25 * {@code MockitoSession} initializes mocks, validates usage and detects incorrect stubbing. 26 * When the session is started it must be concluded with {@link #finishMocking()} 27 * otherwise {@link UnfinishedMockingSessionException} is triggered when the next session is created. 28 * <p> 29 * {@code MockitoSession} is useful when you cannot use {@link MockitoJUnitRunner} or {@link MockitoRule}. 30 * For example, you work with TestNG instead of JUnit. 31 * Another example is when different JUnit runner is in use (Jukito, Springockito) 32 * and it cannot be combined with Mockito's own runner. 33 * <p> 34 * Framework integrators are welcome to use {@code MockitoSession} and give us feedback by commenting on 35 * <a href="https://github.com/mockito/mockito/issues/857">issue 857</a>. 36 * <p> 37 * 38 * Example: 39 * <pre class="code"><code class="java"> 40 * public class ExampleTest { 41 * @Mock Foo foo; 42 * 43 * //Keeping session object in a field so that we can complete session in 'tear down' method. 44 * //It is recommended to hide the session object, along with 'setup' and 'tear down' methods in a base class / runner. 45 * //Keep in mind that you can use Mockito's JUnit runner or rule instead of MockitoSession and get the same behavior. 46 * MockitoSession mockito; 47 * 48 * @Before public void setup() { 49 * //initialize session to start mocking 50 * mockito = Mockito.mockitoSession() 51 * .initMocks(this) 52 * .strictness(Strictness.STRICT_STUBS) 53 * .startMocking(); 54 * } 55 * 56 * @After public void tearDown() { 57 * //It is necessary to finish the session so that Mockito 58 * // can detect incorrect stubbing and validate Mockito usage 59 * //'finishMocking()' is intended to be used in your test framework's 'tear down' method. 60 * mockito.finishMocking(); 61 * } 62 * 63 * // test methods ... 64 * } 65 * </code></pre> 66 * 67 * <p> 68 * Why to use {@code MockitoSession}? 69 * What's the difference between {@code MockitoSession}, {@link MockitoJUnitRunner}, {@link MockitoRule} 70 * and traditional {@link MockitoAnnotations#initMocks(Object)}? 71 * <p> 72 * Great questions! 73 * There is no need to use {@code MockitoSession} if you already use {@link MockitoJUnitRunner} or {@link MockitoRule}. 74 * If you are JUnit user who does not leverage Mockito rule or runner we strongly recommend to do so. 75 * Both the runner and the rule support strict stubbing which can really help driving cleaner tests. 76 * See {@link MockitoJUnitRunner.StrictStubs} and {@link MockitoRule#strictness(Strictness)}. 77 * If you cannot use Mockito's JUnit support (for example, you are on TestNG) {@code MockitoSession} exactly is for you! 78 * You can automatically take advantage of strict stubbing ({@link Strictness}), 79 * automatic initialization of annotated mocks ({@link MockitoAnnotations}), 80 * and extra validation ({@link Mockito#validateMockitoUsage()}). 81 * If you use Mockito annotations with {@link MockitoAnnotations#initMocks(Object)} 82 * but not Mockito runner/rule please try out Mockito's JUnit support (runner or rule) or 83 * start using {@code MockitoSession}. You'll get cleaner tests and better productivity. 84 * <p> 85 * Mockito team would really appreciate feedback about {@code MockitoSession} API. 86 * Help us out by commenting at <a href="https://github.com/mockito/mockito/issues/857">issue 857</a>. 87 * 88 * @since 2.7.0 89 */ 90 @Incubating 91 public interface MockitoSession { 92 93 /** 94 * Changes the strictness of this {@code MockitoSession}. 95 * The new strictness will be applied to operations on mocks and checks performed by {@link #finishMocking()}. 96 * This method is used behind the hood by {@link MockitoRule#strictness(Strictness)} method. 97 * In most healthy tests, this method is not needed. 98 * We keep it for edge cases and when you really need to change strictness in given test method. 99 * For use cases see Javadoc for {@link PotentialStubbingProblem} class. 100 * 101 * @param strictness new strictness for this session. 102 * @since 2.15.0 103 */ 104 @Incubating setStrictness(Strictness strictness)105 void setStrictness(Strictness strictness); 106 107 /** 108 * Must be invoked when the user is done with mocking for given session (test method). 109 * It detects unused stubbings and may throw {@link UnnecessaryStubbingException} 110 * or emit warnings ({@link MockitoHint}) depending on the {@link Strictness} level. 111 * The method also detects incorrect Mockito usage via {@link Mockito#validateMockitoUsage()}. 112 * <p> 113 * In order to implement {@link Strictness} Mockito session keeps track of mocking using {@link MockitoListener}. 114 * This method cleans up the listeners and ensures there is no leftover state after the session finishes. 115 * It is necessary to invoke this method to conclude mocking session. 116 * For more information about session lifecycle see {@link MockitoSessionBuilder#startMocking()}. 117 * <p> 118 * This method is intended to be used in your test framework's 'tear down' method. 119 * In the case of JUnit it is the "@After" method. 120 * <p> 121 * For example, see javadoc for {@link MockitoSession}. 122 * 123 * @see #finishMocking(Throwable) 124 * @since 2.7.0 125 */ 126 @Incubating finishMocking()127 void finishMocking(); 128 129 /** 130 * Must be invoked when the user is done with mocking for given session (test method). 131 * When a {@linkplain Throwable failure} is specified, certain checks are disabled to avoid 132 * confusion that may arise because there are multiple competing failures. Other than that, 133 * this method behaves exactly like {@link #finishMocking()}. 134 * <p> 135 * This method is intended to be used by framework integrations. When using MockitoSession 136 * directly, most users should rather use {@link #finishMocking()}. 137 * {@link MockitoRule} uses this method behind the hood. 138 * 139 * @param failure the exception that caused the test to fail; passing {@code null} is permitted 140 * @see #finishMocking() 141 * @since 2.15.0 142 */ 143 @Incubating finishMocking(Throwable failure)144 void finishMocking(Throwable failure); 145 } 146