@Incubating public class InlineByteBuddyMockMaker extends java.lang.Object implements ClassCreatingMockMaker
This mock maker which uses a combination of the Java instrumentation API and sub-classing rather than creating a new sub-class to create a mock. This way, it becomes possible to mock final types and methods. This mock maker must to be activated explicitly for supporting mocking final types and methods:
This mock maker can be activated by creating the file /mockito-extensions/org.mockito.plugins.MockMaker
containing the text mock-maker-inline
or org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker
.
This mock maker will make a best effort to avoid subclass creation when creating a mock. Otherwise it will use the
org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker
to create the mock class. That means
that the following condition is true
class Foo { }
assert mock(Foo.class).getClass() == Foo.class;
unless any of the following conditions is met, in such case the mock maker fall backs to the the creation of a subclass.
Some type of the JDK cannot be mocked, this includes Class
, String
, and wrapper types.
Nevertheless, final methods of such types are mocked when using the inlining mock maker. Mocking final types and enums does however remain impossible when explicitly requiring serialization support or when adding ancillary interfaces.
Important behavioral changes when using inline-mocks:
java.*
packages.native
methods. Inline mocks require byte code manipulation of a
method where native methods do not offer any byte code to manipulate.synchronized
modifiers from mocked instances.
Note that inline mocks require a Java agent to be attached. Mockito will attempt an attachment of a Java agent upon
loading the mock maker for creating inline mocks. Such runtime attachment is only possible when using a JVM that
is part of a JDK or when using a Java 9 VM. When running on a non-JDK VM prior to Java 9, it is however possible to
manually add the Byte Buddy Java agent jar using the -javaagent
parameter upon starting the JVM. Furthermore, the inlining mock maker requires the VM to support class retransformation
(also known as HotSwap). All major VM distributions such as HotSpot (OpenJDK), J9 (IBM/Websphere) or Zing (Azul)
support this feature.
MockMaker.TypeMockability
Modifier and Type | Field and Description |
---|---|
private BytecodeGenerator |
bytecodeGenerator |
private static java.lang.Throwable |
INITIALIZATION_ERROR |
private static java.lang.instrument.Instrumentation |
INSTRUMENTATION |
private WeakConcurrentMap<java.lang.Object,MockMethodInterceptor> |
mocks |
Constructor and Description |
---|
InlineByteBuddyMockMaker() |
Modifier and Type | Method and Description |
---|---|
<T> T |
createMock(MockCreationSettings<T> settings,
MockHandler handler)
If you want to provide your own implementation of
MockMaker this method should:
Create a proxy object that implements settings.typeToMock and potentially also settings.extraInterfaces .
You may use the information from settings to create/configure your proxy object.
Your proxy object should carry the handler with it. |
<T> java.lang.Class<? extends T> |
createMockType(MockCreationSettings<T> settings) |
MockHandler |
getHandler(java.lang.Object mock)
Returns the handler for the
mock . |
MockMaker.TypeMockability |
isTypeMockable(java.lang.Class<?> type)
Indicates if the given type can be mocked by this mockmaker.
|
private <T> java.lang.RuntimeException |
prettifyFailure(MockCreationSettings<T> mockFeatures,
java.lang.Exception generationFailed) |
void |
resetMock(java.lang.Object mock,
MockHandler newHandler,
MockCreationSettings settings)
Replaces the existing handler on
mock with newHandler . |
private static final java.lang.instrument.Instrumentation INSTRUMENTATION
private static final java.lang.Throwable INITIALIZATION_ERROR
private final BytecodeGenerator bytecodeGenerator
private final WeakConcurrentMap<java.lang.Object,MockMethodInterceptor> mocks
public <T> T createMock(MockCreationSettings<T> settings, MockHandler handler)
MockMaker
MockMaker
this method should:
settings.typeToMock
and potentially also settings.extraInterfaces
.settings
to create/configure your proxy object.handler
with it. For example, if you generate byte code
to create the proxy you could generate an extra field to keep the handler
with the generated object.
Your implementation of MockMaker
is required to provide this instance of handler
when
MockMaker.getHandler(Object)
is called.
createMock
in interface MockMaker
T
- Type of the mock to return, actually the settings.getTypeToMock
.settings
- Mock creation settings like type to mock, extra interfaces and so on.handler
- See MockHandler
.
Do not provide your own implementation at this time. Make sure your implementation of
MockMaker.getHandler(Object)
will return this instance.public <T> java.lang.Class<? extends T> createMockType(MockCreationSettings<T> settings)
createMockType
in interface ClassCreatingMockMaker
private <T> java.lang.RuntimeException prettifyFailure(MockCreationSettings<T> mockFeatures, java.lang.Exception generationFailed)
public MockHandler getHandler(java.lang.Object mock)
MockMaker
mock
. Do not provide your own implementations at this time
because the work on the MockHandler
api is not completed.
Use the instance provided to you by Mockito at MockMaker.createMock(org.mockito.mock.MockCreationSettings<T>, org.mockito.invocation.MockHandler)
or MockMaker.resetMock(java.lang.Object, org.mockito.invocation.MockHandler, org.mockito.mock.MockCreationSettings)
.getHandler
in interface MockMaker
mock
- The mock instance.public void resetMock(java.lang.Object mock, MockHandler newHandler, MockCreationSettings settings)
MockMaker
mock
with newHandler
.
The invocation handler actually store invocations to achieve stubbing and verification. In order to reset the mock, we pass a new instance of the invocation handler.
Your implementation should make sure the newHandler
is correctly associated to passed mock
public MockMaker.TypeMockability isTypeMockable(java.lang.Class<?> type)
MockMaker
Mockmaker may have different capabilities in term of mocking, typically Mockito 1.x's internal mockmaker cannot mock final types. Other implementations, may have different limitations.
isTypeMockable
in interface MockMaker
type
- The type inspected for mockability.