mockit.internal.state.TestRun Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmockit Show documentation
Show all versions of jmockit Show documentation
JMockit is a Java toolkit for developer (unit/integration) testing.
It contains mocking APIs and other tools, supporting both JUnit and TestNG.
The mocking APIs allow all kinds of Java code, without testability restrictions, to be tested
in isolation from selected dependencies.
/*
* Copyright (c) 2006-2011 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.state;
import java.lang.reflect.*;
import java.util.*;
import static java.util.Collections.*;
import mockit.*;
import mockit.internal.annotations.*;
import mockit.internal.capturing.*;
import mockit.internal.expectations.*;
import mockit.internal.expectations.mocking.*;
/**
* A singleton which stores several data structures which in turn hold global state for individual
* test methods, test classes, and for the test run as a whole.
*/
@SuppressWarnings({"ClassWithTooManyFields"})
public final class TestRun
{
private static final TestRun STARTUP_INSTANCE = new TestRun();
private static final Map INSTANCES = synchronizedMap(new HashMap());
static
{
INSTANCES.put(ClassLoader.getSystemClassLoader(), STARTUP_INSTANCE);
}
private static TestRun getInstance()
{
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
TestRun instance = INSTANCES.get(contextCL);
// Certain runtime environments (OpenEJB, at least) change the context class loader to a child of the system
// class loader, so we try looking up the parent class loader before creating a new TestRun instance.
if (instance == null) {
instance = INSTANCES.get(contextCL.getParent());
}
if (instance == null) {
instance = new TestRun();
INSTANCES.put(contextCL, instance);
}
return instance;
}
private TestRun() {}
// Fields with global state ////////////////////////////////////////////////////////////////////////////////////////
private static final ThreadLocal noMockingCount = new ThreadLocal()
{
@Override
protected Integer initialValue() { return 0; }
@Override
public void set(Integer valueToAdd)
{
super.set(get() + valueToAdd);
}
};
// Used only by the Coverage tool:
private int testId;
private Class> currentTestClass;
private Object currentTestInstance;
private Method runningTestMethod;
private SavePoint savePointForTestClass;
private CaptureOfImplementationsForTestClass captureOfSubtypes;
private SharedFieldTypeRedefinitions sharedFieldTypeRedefinitions;
private final ProxyClasses proxyClasses = new ProxyClasses();
private final MockFixture mockFixture = new MockFixture();
private final ExecutingTest executingTest = new ExecutingTest();
private final MockClasses mockClasses = new MockClasses();
// Static "getters" for global state ///////////////////////////////////////////////////////////////////////////////
public static boolean isInsideNoMockingZone() { return noMockingCount.get() > 0; }
public static Class> getCurrentTestClass() { return getInstance().currentTestClass; }
public static Object getCurrentTestInstance() { return getInstance().currentTestInstance; }
public static int getTestId() { return getInstance().testId; }
public static SavePoint getSavePointForTestClass()
{
return getInstance().savePointForTestClass;
}
public static CaptureOfImplementationsForTestClass getCaptureOfSubtypes()
{
return getInstance().captureOfSubtypes;
}
public static SharedFieldTypeRedefinitions getSharedFieldTypeRedefinitions()
{
return getInstance().sharedFieldTypeRedefinitions;
}
public static ProxyClasses proxyClasses() { return getInstance().proxyClasses; }
public static MockFixture mockFixture() { return getInstance().mockFixture; }
public static ExecutingTest getExecutingTest() { return getInstance().executingTest; }
public static RecordAndReplayExecution getRecordAndReplayForRunningTest(boolean create)
{
TestRun testRun = getInstance();
if (testRun.currentTestInstance == null) {
return null;
}
return testRun.executingTest.getRecordAndReplay(testRun.runningTestMethod != null && create);
}
public static MockClasses getMockClasses() { return getInstance().mockClasses; }
public static void verifyExpectationsOnAnnotatedMocks()
{
getMockClasses().getMockStates().verifyExpectations();
}
// Static "mutators" for global state //////////////////////////////////////////////////////////////////////////////
public static void resetExpectationsOnAnnotatedMocks()
{
getMockClasses().getMockStates().resetExpectations();
}
public static void setCurrentTestClass(Class> testClass)
{
getInstance().currentTestClass = testClass;
}
public static void prepareForNextTest()
{
getInstance().testId++;
}
public static void setRunningTestMethod(Method runningTestMethod)
{
TestRun testRun = getInstance();
testRun.runningTestMethod = runningTestMethod;
if (runningTestMethod != null) {
testRun.executingTest.clearRecordAndReplayForVerifications();
}
}
public static void enterNoMockingZone() { noMockingCount.set(1); }
public static void exitNoMockingZone() { noMockingCount.set(-1); }
public static void setRunningIndividualTest(Object testInstance)
{
getInstance().currentTestInstance = testInstance;
}
public static void setSavePointForTestClass(SavePoint savePoint)
{
getInstance().savePointForTestClass = savePoint;
}
public static void setCaptureOfSubtypes(CaptureOfImplementationsForTestClass captureOfSubtypes)
{
getInstance().captureOfSubtypes = captureOfSubtypes;
}
public static void setSharedFieldTypeRedefinitions(SharedFieldTypeRedefinitions redefinitions)
{
getInstance().sharedFieldTypeRedefinitions = redefinitions;
}
public static void finishCurrentTestExecution(boolean clearSharedMocks)
{
TestRun testRun = getInstance();
testRun.runningTestMethod = null;
testRun.executingTest.finishExecution(clearSharedMocks);
}
// Methods to be called only from generated bytecode or from the MockingBridge /////////////////////////////////////
public static Object getMock(int index)
{
return getMockClasses().regularMocks.getMock(index);
}
@SuppressWarnings({"UnusedDeclaration"})
public static Object getStartupMock(int index)
{
return STARTUP_INSTANCE.mockClasses.startupMocks.getMock(index);
}
@SuppressWarnings({"UnusedDeclaration"})
public static Object getMock(Class> mockClass, Object mockedInstance)
{
return getMockClasses().regularMocks.getMock(mockClass, mockedInstance);
}
public static boolean updateMockState(String mockClassDesc, int mockStateIndex)
{
AnnotatedMockStates mockStates = getMockStates(mockClassDesc);
return mockStates.updateMockState(mockClassDesc, mockStateIndex);
}
private static AnnotatedMockStates getMockStates(String mockClassDesc)
{
AnnotatedMockStates mockStates = getMockClasses().getMockStates();
return mockStates.hasStates(mockClassDesc) ? mockStates : STARTUP_INSTANCE.mockClasses.getMockStates();
}
public static void exitReentrantMock(String mockClassDesc, int mockStateIndex)
{
AnnotatedMockStates mockStates = getMockStates(mockClassDesc);
mockStates.exitReentrantMock(mockClassDesc, mockStateIndex);
}
public static Invocation createMockInvocation(String mockClassDesc, int mockStateIndex, Object mockedInstance)
{
AnnotatedMockStates mockStates = getMockStates(mockClassDesc);
return mockStates.createMockInvocation(mockClassDesc, mockStateIndex, mockedInstance);
}
}