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 automated developer testing.
It contains mocking/faking APIs and a code coverage tool, 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 JMockit developers
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.state;
import javax.annotation.*;
import mockit.internal.expectations.*;
import mockit.internal.expectations.state.*;
import mockit.internal.injection.*;
import mockit.internal.expectations.mocking.*;
import mockit.internal.faking.*;
import mockit.internal.util.*;
/**
* 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.
*/
public final class TestRun
{
private static final TestRun INSTANCE = new TestRun();
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;
@Nullable private Class> currentTestClass;
@Nullable private Object currentTestInstance;
@Nullable private FieldTypeRedefinitions fieldTypeRedefinitions;
@Nullable private TestedClassInstantiations testedClassInstantiations;
@Nonnull private final MockFixture mockFixture = new MockFixture();
@Nonnull private final ExecutingTest executingTest = new ExecutingTest();
@Nonnull private final FakeClasses fakeClasses = new FakeClasses();
// Static "getters" for global state ///////////////////////////////////////////////////////////////////////////////
public static boolean isInsideNoMockingZone() { return noMockingCount.get() > 0; }
@Nullable public static Class> getCurrentTestClass() { return INSTANCE.currentTestClass; }
@Nullable public static Object getCurrentTestInstance() { return INSTANCE.currentTestInstance; }
public static int getTestId() { return INSTANCE.testId; }
@Nullable
public static FieldTypeRedefinitions getFieldTypeRedefinitions() { return INSTANCE.fieldTypeRedefinitions; }
@Nullable
public static TestedClassInstantiations getTestedClassInstantiations() { return INSTANCE.testedClassInstantiations; }
@Nonnull public static MockFixture mockFixture() { return INSTANCE.mockFixture; }
@Nonnull public static ExecutingTest getExecutingTest() { return INSTANCE.executingTest; }
@Nullable
public static RecordAndReplayExecution getRecordAndReplayForRunningTest() { return INSTANCE.executingTest.getCurrentRecordAndReplay(); }
@Nonnull
public static RecordAndReplayExecution getOrCreateRecordAndReplayForRunningTest() {
return INSTANCE.executingTest.getOrCreateRecordAndReplay();
}
@Nonnull
public static RecordAndReplayExecution getRecordAndReplayForVerifications() {
return INSTANCE.executingTest.getRecordAndReplayForVerifications();
}
@Nonnull public static FakeClasses getFakeClasses() { return INSTANCE.fakeClasses; }
@Nonnull public static FakeStates getFakeStates() { return INSTANCE.fakeClasses.fakeStates; }
// Static "mutators" for global state //////////////////////////////////////////////////////////////////////////////
public static void setCurrentTestClass(@Nullable Class> testClass) { INSTANCE.currentTestClass = testClass; }
public static void prepareForNextTest() {
INSTANCE.testId++;
INSTANCE.executingTest.setRecordAndReplay(null);
}
public static void enterNoMockingZone() { noMockingCount.set(1); }
public static void exitNoMockingZone() { noMockingCount.set(-1); }
public static void clearNoMockingZone() { noMockingCount.remove(); }
public static void clearCurrentTestInstance() {
INSTANCE.currentTestInstance = null;
}
public static void setRunningIndividualTest(@Nonnull Object testInstance) {
INSTANCE.currentTestInstance = testInstance;
}
public static void setFieldTypeRedefinitions(@Nullable FieldTypeRedefinitions redefinitions) {
INSTANCE.fieldTypeRedefinitions = redefinitions;
}
public static void setTestedClassInstantiations(@Nullable TestedClassInstantiations testedClassInstantiations) {
INSTANCE.testedClassInstantiations = testedClassInstantiations;
}
public static void finishCurrentTestExecution() {
INSTANCE.executingTest.finishExecution();
}
// Methods to be called only from generated bytecode or from the ClassLoadingBridge ////////////////////////////////
@SuppressWarnings({"StaticMethodOnlyUsedInOneClass", "SimplifiableIfStatement"})
public static boolean updateFakeState(@Nonnull String fakeClassDesc, int fakeStateIndex) {
Object fake = getFake(fakeClassDesc);
if (fakeStateIndex < 0) {
return true;
}
return getFakeStates().updateFakeState(fake, fakeStateIndex);
}
@Nonnull
public static Object getFake(@Nonnull String fakeClassDesc) {
return INSTANCE.fakeClasses.getFake(fakeClassDesc);
}
// Other methods ///////////////////////////////////////////////////////////////////////////////////////////////////
public static void ensureThatClassIsInitialized(@Nonnull Class> aClass) {
boolean previousFlag = INSTANCE.executingTest.setShouldIgnoreMockingCallbacks(true);
try {
Class.forName(aClass.getName(), true, aClass.getClassLoader());
}
catch (ClassNotFoundException ignore) {}
catch (LinkageError e) {
StackTrace.filterStackTrace(e);
e.printStackTrace();
}
finally {
INSTANCE.executingTest.setShouldIgnoreMockingCallbacks(previousFlag);
}
}
}