Skip to content

Commit

Permalink
fixup! Fixes mockito#2626 : Introduce MockSettings.mockMaker
Browse files Browse the repository at this point in the history
  • Loading branch information
JojOatXGME committed Sep 3, 2022
1 parent 696385b commit 337cb79
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 7 deletions.
6 changes: 6 additions & 0 deletions src/main/java/org/mockito/Mock.java
Expand Up @@ -13,6 +13,7 @@
import java.lang.annotation.Target;

import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.plugins.MockMaker;
import org.mockito.stubbing.Answer;

/**
Expand Down Expand Up @@ -124,6 +125,11 @@
*/
Strictness strictness() default Strictness.TEST_LEVEL_DEFAULT;

/**
* Mock will be created by the given {@link MockMaker}, see {@link MockSettings#mockMaker(String)}.
*
* @since ${NEXT_VERSION}
*/
String mockMaker() default "";

enum Strictness {
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/org/mockito/MockMakers.java
Expand Up @@ -4,9 +4,36 @@
*/
package org.mockito;

import org.mockito.plugins.MockMaker;

/**
* Constants for built-in implementations of {@code MockMaker}.
* You may use the constants of this class for {@link MockSettings#mockMaker(String)} or {@link Mock#mockMaker()}.
* The string values of these constants may also be used in the resource file <code>mockito-extensions/org.mockito.plugins.MockMaker</code>
* as described in the class documentation of {@link MockMaker}.
*
* @since ${NEXT_VERSION}
*/
public final class MockMakers {
/**
* Inline mock maker which can mock final types, enums and final methods.
* This mock maker cannot mock native methods,
* and it does not support {@link MockSettings#extraInterfaces(Class[]) extra interfaces}.
*
* @see <a href="Mockito.html#39">Mocking final types, enums and final methods</a>
*/
public static final String INLINE = "mock-maker-inline";
/**
* Proxy mock maker which avoids code generation, but can only mock interfaces.
*
* @see <a href="Mockito.html#50">Avoiding code generation when restricting mocks to interfaces</a>
*/
public static final String PROXY = "mock-maker-proxy";
/**
* Subclass mock maker which mocks types by creating subclasses.
* This is the first built-in mock maker which has been provided by Mockito.
* Since this mock maker relies on subclasses, it cannot mock final classes and methods.
*/
public static final String SUBCLASS = "mock-maker-subclass";

private MockMakers() {}
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/mockito/MockSettings.java
Expand Up @@ -15,6 +15,7 @@
import org.mockito.listeners.VerificationStartedListener;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.SerializableMode;
import org.mockito.plugins.MockMaker;
import org.mockito.quality.Strictness;
import org.mockito.stubbing.Answer;

Expand Down Expand Up @@ -382,5 +383,24 @@ public interface MockSettings extends Serializable {
*/
MockSettings strictness(Strictness strictness);

/**
* Specifies the {@code MockMaker} for the mock.
* The default depends on your project as described in the class documentation of {@link MockMaker}.
* You should usually use the default, this option primarily exists to ease migrations.
* You may specify either one of the constants from {@link MockMakers},
* <pre>
* Object mock = Mockito.mock(Object.class, Mockito.withSettings()
* .mockMaker(MockMakers.INLINE));
* </pre>
* or the {@link Class#getName() binary name} of a class which implements the {@code MockMaker} interface.
* <pre>
* Object mock = Mockito.mock(Object.class, Mockito.withSettings()
* .mockMaker("org.awesome.mockito.AwesomeMockMaker"));
* </pre>
*
* @param mockMaker the {@code MockMaker} to use for the mock
* @return settings instance so that you can fluently specify other settings
* @since ${NEXT_VERSION}
*/
MockSettings mockMaker(String mockMaker);
}
23 changes: 20 additions & 3 deletions src/main/java/org/mockito/Mockito.java
Expand Up @@ -105,7 +105,8 @@
* <a href="#49">49. New API for mocking object construction (Since 3.5.0)</a><br/>
* <a href="#50">50. Avoiding code generation when restricting mocks to interfaces (Since 3.12.2)</a><br/>
* <a href="#51">51. New API for marking classes as unmockable (Since 4.1.0)</a><br/>
* <a href="#51">52. New strictness attribute for @Mock annotation and <code>MockSettings.strictness()</code> methods (Since 4.6.0)</a><br/>
* <a href="#52">52. New strictness attribute for @Mock annotation and <code>MockSettings.strictness()</code> methods (Since 4.6.0)</a><br/>
* <a href="#53">53. Specifying mock maker for individual mocks (Since ${NEXT_VERSION})</a><br/>
* </b>
*
* <h3 id="0">0. <a class="meaningful_link" href="#mockito2" name="mockito2">Migrating to Mockito 2</a></h3>
Expand Down Expand Up @@ -1586,7 +1587,7 @@
* released. To define mock behavior and to verify method invocations, use the <code>MockedConstruction</code> that is returned.
* <p>
*
* <h3 id="50">50. <a class="meaningful_link" href="#proxy_mock_maker" name="mocked_construction">Avoiding code generation when only interfaces are mocked</a> (since 3.12.2)</h3>
* <h3 id="50">50. <a class="meaningful_link" href="#proxy_mock_maker" name="proxy_mock_maker">Avoiding code generation when only interfaces are mocked</a> (since 3.12.2)</h3>
*
* The JVM offers the {@link java.lang.reflect.Proxy} facility for creating dynamic proxies of interface types. For most applications, Mockito
* must be capable of mocking classes as supported by the default mock maker, or even final classes, as supported by the inline mock maker. To
Expand All @@ -1609,7 +1610,7 @@
* <p>
*
* <h3 id="52">52. <a class="meaningful_link" href="#mockito_strictness" name="mockito_strictness">
* New strictness attribute for @Mock annotation and <code>MockSettings.strictness()</code> methods (Since 4.6.0)</a></h3>
* New strictness attribute for @Mock annotation and <code>MockSettings.strictness()</code> methods</a> (Since 4.6.0)</h3>
*
* You can now customize the strictness level for a single mock, either using `@Mock` annotation strictness attribute or
* using `MockSettings.strictness()`. This can be useful if you want all of your mocks to be strict,
Expand All @@ -1622,6 +1623,22 @@
* Foo mock = Mockito.mock(Foo.class, withSettings().strictness(Strictness.WARN));
* </code></pre>
*
* <h3 id="53">53. <a class="meaningful_link" href="#individual_mock_maker" name="individual_mock_maker">
* Specifying mock maker for individual mocks</a> (Since ${NEXT_VERSION})</h3>
*
* You may encounter situations where you want to use a different mock maker for a specific test only.
* For example, you might want to migrate to the <a href="#0.2">inline mock maker</a>, but a few test do not work right away.
* In such case, you can (temporarily) use {@link MockSettings#mockMaker(String)} and {@link Mock#mockMaker()}
* to specify the mock maker for a specific mock which is causing the problem.
*
* <pre class="code"><code class="java">
* // using annotation
* &#064;Mock(mockMaker = MockMakers.SUBCLASS)
* Foo mock;
* // using MockSettings.withSettings()
* Foo mock = Mockito.mock(Foo.class, withSettings().mockMaker(MockMakers.SUBCLASS));
* </code></pre>
*
*/
@CheckReturnValue
@SuppressWarnings("unchecked")
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/org/mockito/mock/MockCreationSettings.java
Expand Up @@ -138,8 +138,11 @@ public interface MockCreationSettings<T> {
Strictness getStrictness();

/**
* The {@link MockMaker} which shall by used instead of the default. When
* the return value is {@code null}, the default shall be used.
* Returns the {@link MockMaker} which shall be used to create the mock.
* When the return value is {@code null}, the default shall be used.
*
* @see MockSettings#mockMaker(String)
* @since ${NEXT_VERSION}
*/
String getMockMaker();
}
4 changes: 2 additions & 2 deletions src/main/java/org/mockito/plugins/MockMaker.java
Expand Up @@ -51,10 +51,10 @@
* <p>If you want to use a {@code MockMaker} only for a specific mock,
* you can specify it using {@link MockSettings#mockMaker(String)}.</p>
* <pre>
* // Use a mockmaker shipping with Mockito
* // Use a built-in mock maker
* Object mock = Mockito.mock(Object.class, Mockito.withSettings()
* .mockMaker(MockMakers.INLINE));
* // Or load a mockmaker using a fully qualified class name
* // Or load a mock maker using a fully qualified class name
* Object mock = Mockito.mock(Object.class, Mockito.withSettings()
* .mockMaker("org.awesome.mockito.AwesomeMockMaker"));
* </pre>
Expand Down

0 comments on commit 337cb79

Please sign in to comment.