private void executeTestMethod(FrameworkMethod it, Object target, Object... parameters)
      throws Throwable {
    SavePoint savePoint = new SavePoint();
    TestRun.setSavePointForTestMethod(savePoint);

    Method testMethod = it.getMethod();
    Throwable testFailure = null;
    boolean testFailureExpected = false;

    try {
      Object[] mockParameters = null;
      /** modified by davey.wu * */
      String frameworkMethodName = it.getClass().getName();
      /** 不判断整个类名,是尽量避免代码package重构带来的影响 * */
      boolean isTest4JFrameworkMethod =
          frameworkMethodName.startsWith("org.test4j.junit.")
              && frameworkMethodName.endsWith(".FrameworkMethodWithParameters");
      if (!isTest4JFrameworkMethod) {
        mockParameters =
            createInstancesForMockParameters(target, testMethod, parameters, savePoint);
      }
      /** end modified by davey.wu * */
      createInstancesForTestedFields(target);

      TestRun.setRunningIndividualTest(target);
      it.invokeExplosively(target, mockParameters == null ? parameters : mockParameters);
    } catch (Throwable thrownByTest) {
      testFailure = thrownByTest;
      Class<? extends Throwable> expectedType = testMethod.getAnnotation(Test.class).expected();
      testFailureExpected = expectedType.isAssignableFrom(thrownByTest.getClass());
    } finally {
      concludeTestMethodExecution(savePoint, testFailure, testFailureExpected);
    }
  }
  Object invokeExplosively(FrameworkMethod it, Object target, Object... params) throws Throwable {
    Method method = it.getMethod();
    Class<?> testClass = target == null ? method.getDeclaringClass() : target.getClass();

    handleMockingOutsideTestMethods(it, target, testClass);

    // In case it isn't a test method, but a before/after method:
    if (it.getAnnotation(Test.class) == null) {
      if (shouldPrepareForNextTest && it.getAnnotation(Before.class) != null) {
        prepareForNextTest();
        shouldPrepareForNextTest = false;
      }

      TestRun.setRunningIndividualTest(target);
      TestRun.setSavePointForTestMethod(null);

      try {
        return it.invokeExplosively(target, params);
      } catch (Throwable t) {
        RecordAndReplayExecution.endCurrentReplayIfAny();
        StackTrace.filterStackTrace(t);
        throw t;
      } finally {
        if (it.getAnnotation(After.class) != null) {
          shouldPrepareForNextTest = true;
        }
      }
    }

    if (shouldPrepareForNextTest) {
      prepareForNextTest();
    }

    shouldPrepareForNextTest = true;

    try {
      executeTestMethod(it, target, params);
      return null; // it's a test method, therefore has void return type
    } catch (Throwable t) {
      StackTrace.filterStackTrace(t);
      throw t;
    } finally {
      /** modified by davey.wu * */
      TestRun.finishCurrentTestExecution(true);
      // TestRun.finishCurrentTestExecution(false);
      /** end modified by davey.wu * */
    }
  }
  private boolean isMatchingInstance(
      @Nonnull Object invokedInstance, @Nonnull Expectation expectation) {
    ExpectedInvocation invocation = expectation.invocation;
    assert invocation.instance != null;

    if (isEquivalentInstance(invocation.instance, invokedInstance)) {
      return true;
    }

    if (TestRun.getExecutingTest().isInjectableMock(invokedInstance)) {
      return false;
    }

    if (dynamicMockInstancesToMatch != null) {
      if (containsReference(dynamicMockInstancesToMatch, invokedInstance)) {
        return false;
      }

      Class<?> invokedClass = invocation.instance.getClass();

      for (Object dynamicMock : dynamicMockInstancesToMatch) {
        if (dynamicMock.getClass() == invokedClass) {
          return false;
        }
      }
    }

    return !invocation.matchInstance && expectation.recordPhase != null;
  }
 boolean isEquivalentInstance(
     @Nonnull Object invocationInstance, @Nonnull Object invokedInstance) {
   return invocationInstance == invokedInstance
       || invocationInstance == replacementMap.get(invokedInstance)
       || invocationInstance == instanceMap.get(invokedInstance)
       || invokedInstance == instanceMap.get(invocationInstance)
       || TestRun.getExecutingTest()
           .isInvokedInstanceEquivalentToCapturedInstance(invocationInstance, invokedInstance);
 }
  private boolean isSameMockedClass(@Nullable Object mock1, @Nullable Object mock2) {
    if (mock1 == mock2) {
      return true;
    }

    if (mock1 != null && mock2 != null) {
      Class<?> mockedClass1 = mock1.getClass();
      Class<?> mockedClass2 = mock2.getClass();

      if (mockedClass1 == mockedClass2
          || TestRun.getExecutingTest()
              .isInvokedInstanceEquivalentToCapturedInstance(mock1, mock2)) {
        return true;
      }

      return TestRun.mockFixture().areCapturedClasses(mockedClass1, mockedClass2);
    }

    return false;
  }
  private void handleMockingOutsideTestMethods(
      FrameworkMethod it, Object target, Class<?> testClass) {
    TestRun.enterNoMockingZone();

    try {
      if (target == null) {
        Class<?> currentTestClass = TestRun.getCurrentTestClass();

        if (currentTestClass != null && testClass.isAssignableFrom(currentTestClass)) {
          if (it.getAnnotation(AfterClass.class) != null) {
            cleanUpMocksFromPreviousTestClass();
          }
        } else if (testClass.isAnnotationPresent(SuiteClasses.class)) {
          setUpClassLevelMocksAndStubs(testClass);
        } else if (it.getAnnotation(BeforeClass.class) != null) {
          updateTestClassState(null, testClass);
        }
      } else {
        updateTestClassState(target, testClass);
      }
    } finally {
      TestRun.exitNoMockingZone();
    }
  }
  boolean isToBeMatchedOnInstance(@Nullable Object mock, @Nonnull String mockNameAndDesc) {
    if (mock == null || mockNameAndDesc.charAt(0) == '<') {
      return false;
    }

    if (dynamicMockInstancesToMatch != null
        && containsReference(dynamicMockInstancesToMatch, mock)) {
      return true;
    }

    if (mockedTypesToMatchOnInstances != null) {
      Class<?> mockedClass = GeneratedClasses.getMockedClass(mock);

      if (containsReference(mockedTypesToMatchOnInstances, mockedClass)) {
        return true;
      }
    } else if (TestRun.getExecutingTest().isInjectableMock(mock)) {
      return true;
    }

    return false;
  }
Example #8
0
 @Override
 boolean isToExecuteRealObjectOverride(@Nonnull Object instance) {
   return !TestRun.getExecutingTest().isMockedInstance(instance);
 }
Example #9
0
 @Override
 boolean isToExecuteRealImplementation(@Nullable Object instance) {
   return instance == null || !TestRun.getExecutingTest().isMockedInstance(instance);
 }
Example #10
0
 @Override
 boolean isWithRealImplementation(@Nullable Object instance) {
   return instance == null || !TestRun.getExecutingTest().isInjectableMock(instance);
 }
Example #11
0
 @Override
 boolean isToExecuteRealImplementation(@Nullable Object instance) {
   return instance != null && !TestRun.mockFixture().isInstanceOfMockedClass(instance);
 }
Example #12
0
 void registerRead() {
   int testId = TestRun.getTestId();
   testIdsToAssignments.put(testId, null);
   readCount++;
 }
Example #13
0
 void registerAssignment() {
   int testId = TestRun.getTestId();
   testIdsToAssignments.put(testId, Boolean.TRUE);
   writeCount++;
 }
 /**
  * Discards any mocks set up for the specified classes that are currently in effect, for all test
  * scopes: the current test method (if any), the current test (which starts with the first
  * "before" method and continues until the last "after" method), the current test class (which
  * includes all code from the first "before class" method to the last "after class" method), and
  * the current test suite.
  *
  * <p>Notice that if one of the given real classes has a mock class applied at the level of the
  * test class, calling this method would negate the application of that mock class. JMockit will
  * automatically restore classes mocked by a test at the end of its execution, as well as all
  * classes mocked for the test class as a whole (through a "before class" method or an
  * {@code @UsingMocksAndStubs} annotation) before the first test in the next test class is
  * executed.
  *
  * @param realClasses one or more real classes from production code, which may have mocked methods
  */
 public static void tearDownMocks(Class<?>... realClasses) {
   Set<Class<?>> classesToRestore = new HashSet<Class<?>>();
   Collections.addAll(classesToRestore, realClasses);
   TestRun.mockFixture().restoreAndRemoveRedefinedClasses(classesToRestore);
 }
 /**
  * Discards any mocks currently in effect, for all test scopes: the current test method (if any),
  * the current test (which starts with the first "before" method and continues until the last
  * "after" method), the current test class (which includes all code from the first "before class"
  * method to the last "after class" method), and the current test suite.
  *
  * <p>Notice that a call to this method will tear down <em>all</em> mock classes that were applied
  * through use of the Mockups API that are still in effect, as well as any mock classes or stubs
  * applied to the current test class through {@code @UsingMocksAndStubs}. In other words, it would
  * effectively prevent mocks to be set up at the test class and test suite levels. So, use it only
  * if necessary and if it won't discard mock classes that should remain in effect. Consider using
  * {@link #tearDownMocks(Class...)} instead, which lets you restrict the set of real classes to be
  * restored.
  *
  * <p>JMockit will automatically restore classes mocked by a test at the end of its execution, as
  * well as all classes mocked for the test class as a whole (through a "before class" method or an
  * {@code @UsingMocksAndStubs} annotation) before the first test in the next test class is
  * executed.
  *
  * @see <a
  *     href="http://code.google.com/p/jmockit/source/browse/trunk/main/test/mockit/MockAnnotationsTest.java#450">
  *     Example</a>
  */
 public static void tearDownMocks() {
   TestRun.mockFixture().restoreAndRemoveRedefinedClasses(null);
   TestRun.getMockClasses().getRegularMocks().discardInstances();
 }