Skip to content

Commit

Permalink
[ci maven-central-release] Merge pull request #2004 from mockito/pre-…
Browse files Browse the repository at this point in the history
…release-3.5.0

Pre release 3.5.0
  • Loading branch information
raphw committed Aug 15, 2020
2 parents ce8cc98 + 5b4e612 commit 7a56cff
Show file tree
Hide file tree
Showing 69 changed files with 2,700 additions and 582 deletions.
40 changes: 40 additions & 0 deletions src/main/java/org/mockito/MockedConstruction.java
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito;

import java.lang.reflect.Constructor;
import java.util.List;

/**
* Represents a mock of any object construction of the represented type. Within the scope of the
* mocked construction, the invocation of any interceptor will generate a mock which will be
* prepared as specified when generating this scope. The mock can also be received via this
* instance.
* <p>
* If the {@link Mock} annotation is used on fields or method parameters of this type, a mocked
* construction is created instead of a regular mock. The mocked construction is activated and
* released upon completing any relevant test.
*
* @param <T> The type for which the construction is being mocked.
*/
@Incubating
public interface MockedConstruction<T> extends ScopedMock {

List<T> constructed();

interface Context {

int getCount();

Constructor<?> constructor();

List<?> arguments();
}

interface MockInitializer<T> {

void prepare(T mock, Context context) throws Throwable;
}
}
20 changes: 1 addition & 19 deletions src/main/java/org/mockito/MockedStatic.java
Expand Up @@ -24,7 +24,7 @@
* @param <T> The type being mocked.
*/
@Incubating
public interface MockedStatic<T> extends AutoCloseable {
public interface MockedStatic<T> extends ScopedMock {

/**
* See {@link Mockito#when(Object)}.
Expand Down Expand Up @@ -63,24 +63,6 @@ default void verify(Verification verification) {
*/
void verifyNoInteractions();

/**
* Checks if this mock is closed.
*
* @return {@code true} if this mock is closed.
*/
boolean isClosed();

/**
* Releases this static mock and throws a {@link org.mockito.exceptions.base.MockitoException} if closed already.
*/
@Override
void close();

/**
* Releases this static mock and is non-operational if already released.
*/
void closeOnDemand();

interface Verification {

void apply() throws Throwable;
Expand Down
188 changes: 175 additions & 13 deletions src/main/java/org/mockito/Mockito.java
Expand Up @@ -28,18 +28,10 @@
import org.mockito.quality.Strictness;
import org.mockito.session.MockitoSessionBuilder;
import org.mockito.session.MockitoSessionLogger;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.Answer1;
import org.mockito.stubbing.LenientStubber;
import org.mockito.stubbing.OngoingStubbing;
import org.mockito.stubbing.Stubber;
import org.mockito.stubbing.Stubbing;
import org.mockito.stubbing.VoidAnswer1;
import org.mockito.verification.After;
import org.mockito.verification.Timeout;
import org.mockito.verification.VerificationAfterDelay;
import org.mockito.verification.VerificationMode;
import org.mockito.verification.VerificationWithTimeout;
import org.mockito.stubbing.*;
import org.mockito.verification.*;

import java.util.function.Function;

/**
* <p align="left"><img src="logo.png" srcset="logo@2x.png 2x" alt="Mockito logo"/></p>
Expand Down Expand Up @@ -106,6 +98,7 @@
* <a href="#46">46. New <code>Mockito.lenient()</code> and <code>MockSettings.lenient()</code> methods (Since 2.20.0)</a><br/>
* <a href="#47">47. New API for clearing mock state in inline mocking (Since 2.25.0)</a><br/>
* <a href="#48">48. New API for mocking static methods (Since 3.4.0)</a><br/>
* <a href="#49">49. New API for mocking object construction (Since 3.5.0)</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 @@ -1565,9 +1558,32 @@
* assertEquals("foo", Foo.method());
* </code></pre>
*
* Due to the defined scope of the static mock, it returns to its original behvior once the scope is released. To define mock
* Due to the defined scope of the static mock, it returns to its original behavior once the scope is released. To define mock
* behavior and to verify static method invocations, use the <code>MockedStatic</code> that is returned.
* <p>
*
* <h3 id="49">49. <a class="meaningful_link" href="#mocked_construction" name="mocked_construction">Mocking object construction</a> (since 3.5.0)</h3>
*
* When using the <a href="#0.2">inline mock maker</a>, it is possible to generate mocks on constructor invocations within the current
* thread and a user-defined scope. This way, Mockito assures that concurrently and sequentially running tests do not interfere.
*
* To make sure a constructor mocks remain temporary, it is recommended to define the scope within a try-with-resources construct.
* In the following example, the <code>Foo</code> type's construction would generate a mock:
*
* <pre class="code"><code class="java">
* assertEquals("foo", Foo.method());
* try (MockedConstruction<Foo> mocked = mockConstruction(Foo.class)) {
* Foo foo = new Foo();
* when(foo.method()).thenReturn("bar");
* assertEquals("bar", foo.method());
* verify(foo).method();
* }
* assertEquals("foo", foo.method());
* </code></pre>
*
* Due to the defined scope of the mocked construction, object construction returns to its original behavior once the scope is
* released. To define mock behavior and to verify static method invocations, use the <code>MockedConstruction</code> that is returned.
* <p>
*/
@SuppressWarnings("unchecked")
public class Mockito extends ArgumentMatchers {
Expand Down Expand Up @@ -2144,6 +2160,152 @@ public static <T> MockedStatic<T> mockStatic(Class<T> classToMock, MockSettings
return MOCKITO_CORE.mockStatic(classToMock, mockSettings);
}

/**
* Creates a thread-local mock controller for all constructions of the given class.
* The returned object's {@link MockedConstruction#close()} method must be called upon completing the
* test or the mock will remain active on the current thread.
* <p>
* See examples in javadoc for {@link Mockito} class
*
* @param classToMock non-abstract class of which constructions should be mocked.
* @param defaultAnswer the default answer for the first created mock.
* @param additionalAnswers the default answer for all additional mocks. For any access mocks, the
* last answer is used. If this array is empty, the {@code defaultAnswer} is used.
* @return mock controller
*/
@Incubating
@CheckReturnValue
public static <T> MockedConstruction<T> mockConstructionWithAnswer(
Class<T> classToMock, Answer defaultAnswer, Answer... additionalAnswers) {
return mockConstruction(
classToMock,
context -> {
if (context.getCount() == 1 || additionalAnswers.length == 0) {
return withSettings().defaultAnswer(defaultAnswer);
} else if (context.getCount() >= additionalAnswers.length) {
return withSettings()
.defaultAnswer(additionalAnswers[additionalAnswers.length - 1]);
} else {
return withSettings()
.defaultAnswer(additionalAnswers[context.getCount() - 2]);
}
},
(mock, context) -> {});
}

/**
* Creates a thread-local mock controller for all constructions of the given class.
* The returned object's {@link MockedConstruction#close()} method must be called upon completing the
* test or the mock will remain active on the current thread.
* <p>
* See examples in javadoc for {@link Mockito} class
*
* @param classToMock non-abstract class of which constructions should be mocked.
* @return mock controller
*/
@Incubating
@CheckReturnValue
public static <T> MockedConstruction<T> mockConstruction(Class<T> classToMock) {
return mockConstruction(classToMock, index -> withSettings(), (mock, context) -> {});
}

/**
* Creates a thread-local mock controller for all constructions of the given class.
* The returned object's {@link MockedConstruction#close()} method must be called upon completing the
* test or the mock will remain active on the current thread.
* <p>
* See examples in javadoc for {@link Mockito} class
*
* @param classToMock non-abstract class of which constructions should be mocked.
* @param mockInitializer a callback to prepare a mock's methods after its instantiation.
* @return mock controller
*/
@Incubating
@CheckReturnValue
public static <T> MockedConstruction<T> mockConstruction(
Class<T> classToMock, MockedConstruction.MockInitializer<T> mockInitializer) {
return mockConstruction(classToMock, withSettings(), mockInitializer);
}

/**
* Creates a thread-local mock controller for all constructions of the given class.
* The returned object's {@link MockedConstruction#close()} method must be called upon completing the
* test or the mock will remain active on the current thread.
* <p>
* See examples in javadoc for {@link Mockito} class
*
* @param classToMock non-abstract class of which constructions should be mocked.
* @param mockSettings the mock settings to use.
* @return mock controller
*/
@Incubating
@CheckReturnValue
public static <T> MockedConstruction<T> mockConstruction(
Class<T> classToMock, MockSettings mockSettings) {
return mockConstruction(classToMock, context -> mockSettings);
}

/**
* Creates a thread-local mock controller for all constructions of the given class.
* The returned object's {@link MockedConstruction#close()} method must be called upon completing the
* test or the mock will remain active on the current thread.
* <p>
* See examples in javadoc for {@link Mockito} class
*
* @param classToMock non-abstract class of which constructions should be mocked.
* @param mockSettingsFactory the mock settings to use.
* @return mock controller
*/
@Incubating
@CheckReturnValue
public static <T> MockedConstruction<T> mockConstruction(
Class<T> classToMock,
Function<MockedConstruction.Context, MockSettings> mockSettingsFactory) {
return mockConstruction(classToMock, mockSettingsFactory, (mock, context) -> {});
}

/**
* Creates a thread-local mock controller for all constructions of the given class.
* The returned object's {@link MockedConstruction#close()} method must be called upon completing the
* test or the mock will remain active on the current thread.
* <p>
* See examples in javadoc for {@link Mockito} class
*
* @param classToMock non-abstract class of which constructions should be mocked.
* @param mockSettings the settings to use.
* @param mockInitializer a callback to prepare a mock's methods after its instantiation.
* @return mock controller
*/
@Incubating
@CheckReturnValue
public static <T> MockedConstruction<T> mockConstruction(
Class<T> classToMock,
MockSettings mockSettings,
MockedConstruction.MockInitializer<T> mockInitializer) {
return mockConstruction(classToMock, index -> mockSettings, mockInitializer);
}

/**
* Creates a thread-local mock controller for all constructions of the given class.
* The returned object's {@link MockedConstruction#close()} method must be called upon completing the
* test or the mock will remain active on the current thread.
* <p>
* See examples in javadoc for {@link Mockito} class
*
* @param classToMock non-abstract class of which constructions should be mocked.
* @param mockSettingsFactory a function to create settings to use.
* @param mockInitializer a callback to prepare a mock's methods after its instantiation.
* @return mock controller
*/
@Incubating
@CheckReturnValue
public static <T> MockedConstruction<T> mockConstruction(
Class<T> classToMock,
Function<MockedConstruction.Context, MockSettings> mockSettingsFactory,
MockedConstruction.MockInitializer<T> mockInitializer) {
return MOCKITO_CORE.mockConstruction(classToMock, mockSettingsFactory, mockInitializer);
}

/**
* Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called.
* <p>
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/org/mockito/ScopedMock.java
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito;

/**
* Represents a mock with a thread-local explicit scope. Scoped mocks must be closed by the entity
* that activates the scoped mock.
*/
@Incubating
public interface ScopedMock extends AutoCloseable {

/**
* Checks if this mock is closed.
*
* @return {@code true} if this mock is closed.
*/
boolean isClosed();

/**
* Closes this scoped mock and throws an exception if already closed.
*/
@Override
void close();

/**
* Releases this scoped mock and is non-operational if already released.
*/
void closeOnDemand();
}
Expand Up @@ -13,6 +13,13 @@
*/
public class InstantiationException extends MockitoException {

/**
* @since 3.5.0
*/
public InstantiationException(String message) {
super(message);
}

/**
* @since 2.15.4
*/
Expand Down

0 comments on commit 7a56cff

Please sign in to comment.