Ejemplo n.º 1
0
  public Object handle(Invocation invocation) throws Throwable {
    if (invocationContainerImpl.hasAnswersForStubbing()) {
      invocation.setPhase(InvocationPhase.DEFINE);
      // stubbing voids with stubVoid() or doAnswer() style
      InvocationMatcher invocationMatcher =
          matchersBinder.bindMatchers(mockingProgress.getArgumentMatcherStorage(), invocation);
      invocationContainerImpl.setMethodForStubbing(invocationMatcher);
      return null;
    }
    VerificationMode verificationMode = mockingProgress.pullVerificationMode();

    InvocationMatcher invocationMatcher =
        matchersBinder.bindMatchers(mockingProgress.getArgumentMatcherStorage(), invocation);

    mockingProgress.validateState();

    // if verificationMode is not null then someone is doing verify()
    if (verificationMode != null) {
      invocation.setPhase(InvocationPhase.VERIFY);
      // We need to check if verification was started on the correct mock
      // - see VerifyingWithAnExtraCallToADifferentMockTest (bug 138)
      if (((MockAwareVerificationMode) verificationMode).getMock() == invocation.getMock()) {
        VerificationDataImpl data =
            createVerificationData(invocationContainerImpl, invocationMatcher);
        verificationMode.verify(data);
        return null;
      } else {
        // this means there is an invocation on a different mock. Re-adding verification mode
        // - see VerifyingWithAnExtraCallToADifferentMockTest (bug 138)
        mockingProgress.verificationStarted(verificationMode);
      }
    }

    // prepare invocation for stubbing
    invocationContainerImpl.setInvocationForPotentialStubbing(invocationMatcher);
    OngoingStubbingImpl<T> ongoingStubbing = new OngoingStubbingImpl<T>(invocationContainerImpl);
    mockingProgress.reportOngoingStubbing(ongoingStubbing);

    // look for existing answer for this invocation
    StubbedInvocationMatcher stubbedInvocation = invocationContainerImpl.findAnswerFor(invocation);

    if (stubbedInvocation != null) {
      invocation.setPhase(InvocationPhase.EXECUTE);
      stubbedInvocation.captureArgumentsFrom(invocation);
      return stubbedInvocation.answer(invocation);
    } else {
      invocation.setPhase(InvocationPhase.DEFINE);
      Object ret = mockSettings.getDefaultAnswer().answer(invocation);

      // redo setting invocation for potential stubbing in case of partial
      // mocks / spies.
      // Without it, the real method inside 'when' might have delegated
      // to other self method and overwrite the intended stubbed method
      // with a different one. The reset is required to avoid runtime exception that validates
      // return type with stubbed method signature.
      invocationContainerImpl.resetInvocationForPotentialStubbing(invocationMatcher);
      return ret;
    }
  }
  public StubbedInvocationMatcher findAnswerFor(Invocation invocation) {
    synchronized (stubbed) {
      for (StubbedInvocationMatcher s : stubbed) {
        if (s.matches(invocation)) {
          s.markStubUsed(invocation);
          invocation.markStubbed(new StubInfoImpl(s));
          return s;
        }
      }
    }

    return null;
  }