Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2006-2013 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit;
import java.lang.reflect.*;
import java.util.*;
import org.jetbrains.annotations.*;
import mockit.internal.mockups.*;
import mockit.internal.startup.*;
import mockit.internal.state.*;
import mockit.internal.util.*;
/**
* A base class used in the creation of a mock-up for a class or interface.
* Such mock-ups can be used in state-based unit tests or as fake implementations for use in
* integration tests.
*
*
* // Define and apply a mock-up before exercising the code under test:
* new MockUp<SomeClass>() {
* @Mock int someMethod(int i) { assertTrue(i > 0); return 123; }
* @Mock(maxInvocations = 2) void anotherMethod(int i, String s) { /* validate arguments */ }
* };
*
* One or more mock methods annotated {@linkplain Mock as such} must be defined in the concrete subclass.
* Each {@code @Mock} method should have a matching method or constructor in the mocked class/interface.
* At runtime, the execution of a mocked method/constructor will get redirected to the corresponding mock method.
*
* In the Tutorial
*
* @param specifies the type (class, interface, etc.) to be mocked; multiple interfaces can be mocked by defining
* a type variable in the test class or test method, and using it as the type argument;
* if the type argument itself is a parameterized type, then only its raw type is considered for mocking
*
* @see #MockUp()
* @see #MockUp(Class)
* @see #getMockInstance()
* @see #tearDown()
*/
public abstract class MockUp
{
static { Startup.verifyInitialization(); }
private Set> classesToRestore;
private final T mockInstance;
/**
* Applies the {@linkplain Mock mock methods} defined in the concrete subclass to the class or interface specified
* through the type parameter.
*
* When one or more interfaces are specified to be mocked, a mocked proxy class that implements the interfaces is
* created, with the proxy instance made available through a call to {@link #getMockInstance()}.
*
* @throws IllegalArgumentException if no type to be mocked was specified;
* or if there is a mock method for which no corresponding real method or constructor is found;
* or if the real method matching a mock method is {@code abstract}
*
* @see #MockUp(Class)
*/
protected MockUp()
{
validateMockingAllowed();
tearDownPreviousMockUpIfSameMockClassAlreadyApplied();
Type typeToMock = MockClassSetup.getTypeToMock(getClass());
if (typeToMock instanceof Class>) {
//noinspection unchecked
mockInstance = redefineClassOrImplementInterface((Class) typeToMock, null);
}
else if (typeToMock instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType) typeToMock;
//noinspection unchecked
Class realClass = (Class) parameterizedType.getRawType();
mockInstance = redefineClassOrImplementInterface(realClass, parameterizedType);
}
else { // a TypeVariable
mockInstance = createMockInstanceForMultipleInterfaces(typeToMock);
}
}
private void validateMockingAllowed()
{
if (TestRun.isInsideNoMockingZone()) {
throw new IllegalStateException("Invalid place to apply a mock-up");
}
}
private void tearDownPreviousMockUpIfSameMockClassAlreadyApplied()
{
Class> mockClass = getClass();
MockUp> previousMock = TestRun.getMockClasses().findMock(mockClass);
if (previousMock != null) {
previousMock.tearDown();
}
}
@Nullable
private T redefineClassOrImplementInterface(@NotNull Class classToMock, @Nullable ParameterizedType typeToMock)
{
if (classToMock.isInterface()) {
return new MockedImplementationClass(this).generate(classToMock, typeToMock);
}
classesToRestore = redefineMethods(classToMock, typeToMock);
return null;
}
@Nullable private Set> redefineMethods(@NotNull Class realClass, @Nullable ParameterizedType mockedType)
{
return Startup.initializing ? null : new MockClassSetup(realClass, mockedType, this, null).redefineMethods();
}
@NotNull private T createMockInstanceForMultipleInterfaces(@NotNull Type typeToMock)
{
T proxy = EmptyProxy.Impl.newEmptyProxy(null, typeToMock);
//noinspection unchecked
redefineMethods((Class) proxy.getClass(), null);
return proxy;
}
/**
* Applies the {@linkplain Mock mock methods} defined in the concrete subclass to the given class/interface.
*
* In most cases, the constructor with no parameters can be used. This variation should be used only when the type
* to be mocked is not accessible or known to the test.
*
* @see #MockUp()
*/
@SuppressWarnings("unchecked")
protected MockUp(Class> classToMock)
{
validateMockingAllowed();
tearDownPreviousMockUpIfSameMockClassAlreadyApplied();
if (classToMock.isInterface()) {
mockInstance = new MockedImplementationClass(this).generate((Class) classToMock, null);
}
else {
classesToRestore = redefineMethods((Class) classToMock, null);
mockInstance = null;
}
}
/**
* Returns the mock instance created for the mocked interface(s), or {@literal null} if a class was specified to be
* mocked instead.
* This mock instance belongs to a dynamically generated class which implements the mocked interface(s).
*
* For a given mock-up instance, this method always returns the same mock instance.
*
* All methods in the generated implementation class are empty, with non-void methods returning a default value
* according to the return type: {@literal 0} for {@code int}, {@literal null} for a reference type, and so on.
*
* The {@code equals}, {@code hashCode}, and {@code toString} methods inherited from {@code java.lang.Object} are
* overridden with an appropriate implementation in each case:
* {@code equals} is implemented by comparing the two object references (the mock instance and the method argument)
* for equality; {@code hashCode} is implemented to return the identity hash code for the mock instance; and
* {@code toString} returns the standard string representation that {@code Object#toString} would have returned.
*/
public final T getMockInstance() { return mockInstance; }
/**
* Discards the mock methods originally set up by instantiating this mock-up object, restoring mocked methods to
* their original behaviors.
*
* JMockit will automatically restore classes mocked by a test at the end of its execution, as well as classes
* mocked for the whole test class before the first test in the next test class is executed.
* Therefore, this method should rarely be used, if ever.
*/
public final void tearDown()
{
if (classesToRestore != null) {
TestRun.mockFixture().restoreAndRemoveRedefinedClasses(classesToRestore);
TestRun.getMockClasses().removeMock(this);
classesToRestore = null;
}
}
}