예제 #1
0
파일: Mock.cs 프로젝트: tomchavakis/moq4
        private static void VerifyCalls(
            Mock targetMock,
            MethodCall expected,
            LambdaExpression expression,
            Times times)
        {
            var allInvocations          = targetMock.MutableInvocations.ToArray();
            var matchingInvocations     = allInvocations.Where(expected.Matches).ToArray();
            var matchingInvocationCount = matchingInvocations.Length;

            if (!times.Verify(matchingInvocationCount))
            {
                var setups = targetMock.Setups.ToArrayLive(oc => AreSameMethod(oc.SetupExpression, expression));
                throw MockException.NoMatchingCalls(expected, setups, allInvocations, expression, times, matchingInvocationCount);
            }
            else
            {
                foreach (var matchingInvocation in matchingInvocations)
                {
                    matchingInvocation.MarkAsVerified();
                }
            }

            bool AreSameMethod(LambdaExpression l, LambdaExpression r) =>
            l.Body is MethodCallExpression lc && r.Body is MethodCallExpression rc && lc.Method == rc.Method;
        }
예제 #2
0
        public override InterceptionAction Handle(Invocation invocation, Mock mock)
        {
            var matchedSetup = mock.Setups.FindMatchFor(invocation);

            if (matchedSetup != null)
            {
                matchedSetup.Condition?.EvaluatedSuccessfully();

                if (matchedSetup.IsVerifiable)
                {
                    invocation.MarkAsMatchedByVerifiableSetup();
                }
                else
                {
                    invocation.MarkAsMatchedBySetup();
                }

                matchedSetup.SetOutParameters(invocation);

                // We first execute, as there may be a Throws
                // and therefore we might never get to the
                // next line.
                matchedSetup.Execute(invocation);
                return(InterceptionAction.Stop);
            }
            else if (mock.Behavior == MockBehavior.Strict)
            {
                throw MockException.NoSetup(invocation);
            }
            else
            {
                return(InterceptionAction.Continue);
            }
        }
예제 #3
0
        internal bool TryVerify(Func <ISetup, bool> predicate, out MockException error)
        {
            foreach (Invocation invocation in this.MutableInvocations)
            {
                invocation.MarkAsVerifiedIfMatchedBy(predicate);
            }

            var errors = new List <MockException>();

            foreach (var setup in this.MutableSetups.ToArray(predicate))
            {
                if (predicate(setup) && !setup.TryVerify(recursive: true, predicate, out var e) && e.IsVerificationError)
                {
                    errors.Add(e);
                }
            }

            if (errors.Count > 0)
            {
                error = MockException.Combined(
                    errors,
                    preamble: string.Format(CultureInfo.CurrentCulture, Resources.VerificationErrorsOfMock, this));
                return(false);
            }
            else
            {
                error = null;
                return(true);
            }
        }
예제 #4
0
        private bool TryVerifyAll(out MockException error)
        {
            foreach (Invocation invocation in this.MutableInvocations)
            {
                invocation.MarkAsVerifiedIfMatchedBySetup();
            }

            var uninvokedSetups = this.Setups.ToArrayLive(setup => !setup.TryVerifyAll());

            if (uninvokedSetups.Length > 0)
            {
                error = MockException.UnmatchedSetups(this, uninvokedSetups);
                return(false);
            }

            foreach (var inner in this.InnerMocks.Values)
            {
                if (!inner.Mock.TryVerifyAll(out error))
                {
                    return(false);
                }
            }

            error = null;
            return(true);
        }
예제 #5
0
        public override void Execute(Invocation invocation)
        {
            base.Execute(invocation);

            if (this.returnValueKind == ReturnValueKind.CallBase)
            {
                invocation.ReturnBase();
            }
            else if (this.valueDel != null)
            {
                invocation.Return(this.valueDel.HasCompatibleParameterList(new ParameterInfo[0])
                                        ? valueDel.InvokePreserveStack()                       //we need this, for the user to be able to use parameterless methods
                                        : valueDel.InvokePreserveStack(invocation.Arguments)); //will throw if parameters mismatch
            }
            else if (this.Mock.Behavior == MockBehavior.Strict)
            {
                throw MockException.ReturnValueRequired(invocation);
            }
            else
            {
                invocation.Return(this.ReturnType.GetDefaultValue());
            }

            this.afterReturnCallback?.Invoke(invocation.Arguments);
        }
예제 #6
0
        internal void Verify(Func <ISetup, bool> predicate, HashSet <Mock> verifiedMocks)
        {
            if (verifiedMocks.Add(this) == false)
            {
                // This mock has already been verified; don't verify it again.
                // (We can end up here e.g. when there are loops in the inner mock object graph.)
                return;
            }

            foreach (Invocation invocation in this.MutableInvocations)
            {
                invocation.MarkAsVerifiedIfMatchedBy(predicate);
            }

            var errors = new List <MockException>();

            foreach (var setup in this.MutableSetups.ToArray(setup => !setup.IsOverridden && !setup.IsConditional && predicate(setup)))
            {
                try
                {
                    setup.Verify(recursive: true, predicate, verifiedMocks);
                }
                catch (MockException error) when(error.IsVerificationError)
                {
                    errors.Add(error);
                }
            }

            if (errors.Count > 0)
            {
                throw MockException.Combined(
                          errors,
                          preamble: string.Format(CultureInfo.CurrentCulture, Resources.VerificationErrorsOfMock, this));
            }
        }
예제 #7
0
파일: Setup.cs 프로젝트: mujdatdinc/moq4
 protected virtual void VerifySelf()
 {
     if (!this.IsMatched)
     {
         throw MockException.UnmatchedSetup(this);
     }
 }
예제 #8
0
 public static void Handle(Invocation invocation, Mock mock)
 {
     if (mock.Behavior == MockBehavior.Strict)
     {
         throw MockException.NoSetup(invocation);
     }
 }
예제 #9
0
파일: Mock.cs 프로젝트: belav/moq4
        internal static void Verify(
            Mock mock,
            LambdaExpression expression,
            Times times,
            string failMessage
            )
        {
            Guard.NotNull(times, nameof(times));

            var invocationCount = Mock.GetMatchingInvocationCount(
                mock,
                expression,
                out var invocationsToBeMarkedAsVerified
                );

            if (times.Validate(invocationCount))
            {
                foreach (var(invocation, part) in invocationsToBeMarkedAsVerified)
                {
                    part.SetupEvaluatedSuccessfully(invocation);
                    invocation.MarkAsVerified();
                }
            }
            else
            {
                throw MockException.NoMatchingCalls(
                          mock,
                          expression,
                          failMessage,
                          times,
                          invocationCount
                          );
            }
        }
예제 #10
0
        internal static MockException FromInnerMockOf(Setup setup, MockException error)
        {
            var message = new StringBuilder();

            message.AppendLine(string.Format(CultureInfo.CurrentCulture, Resources.VerificationErrorsOfInnerMock, setup)).TrimEnd().AppendLine()
            .AppendLine();

            message.AppendIndented(error.Message, count: 3);

            return(new MockException(error.Reasons, message.ToString()));
        }
예제 #11
0
파일: Mock.cs 프로젝트: belav/moq4
        private static void VerifyNoOtherCalls(Mock mock, HashSet <Mock> verifiedMocks)
        {
            if (!verifiedMocks.Add(mock))
            {
                return;
            }

            var unverifiedInvocations = mock.MutableInvocations.ToArray(
                invocation => !invocation.IsVerified
                );

            var innerMockSetups = mock.MutableSetups.GetInnerMockSetups();

            if (unverifiedInvocations.Any())
            {
                // There are some invocations that shouldn't require explicit verification by the user.
                // The intent behind a `Verify` call for a call expression like `m.A.B.C.X` is probably
                // to verify `X`. If that succeeds, it's reasonable to expect that `m.A`, `m.A.B`, and
                // `m.A.B.C` have implicitly been verified as well. Below, invocations such as those to
                // the left of `X` are referred to as "transitive" (for lack of a better word).
                if (innerMockSetups.Any())
                {
                    for (int i = 0, n = unverifiedInvocations.Length; i < n; ++i)
                    {
                        // In order for an invocation to be "transitive", its return value has to be a
                        // sub-object (inner mock); and that sub-object has to have received at least
                        // one call:
                        var wasTransitiveInvocation =
                            innerMockSetups.TryFind(unverifiedInvocations[i]) is Setup inner &&
                            inner.InnerMock.MutableInvocations.Any();
                        if (wasTransitiveInvocation)
                        {
                            unverifiedInvocations[i] = null;
                        }
                    }
                }

                // "Transitive" invocations have been nulled out. Let's see what's left:
                var remainingUnverifiedInvocations = unverifiedInvocations.Where(i => i != null);
                if (remainingUnverifiedInvocations.Any())
                {
                    throw MockException.UnverifiedInvocations(mock, remainingUnverifiedInvocations);
                }
            }

            // Perform verification for all automatically created sub-objects (that is, those
            // created by "transitive" invocations):
            foreach (var inner in innerMockSetups)
            {
                VerifyNoOtherCalls(inner.InnerMock, verifiedMocks);
            }
        }
예제 #12
0
        private void Verify(Action <ISetup> verifyLast)
        {
            Debug.Assert(verifyLast != null);
            Debug.Assert(this.parts.Count > 1);

            try
            {
                foreach (var part in this.parts.Take(this.parts.Count - 1))
                {
                    part.Verify(recursive: false);
                }
                verifyLast(this.parts.Last());
            }
            catch (MockException error) when(error.IsVerificationError)
            {
                throw MockException.FromInnerMockOf(this, error);
            }
        }
예제 #13
0
        /// <summary>
        ///   Verifies this setup and those of its inner mock (if present and known).
        /// </summary>
        /// <param name="recursive">
        ///   Specifies whether recursive verification should be performed.
        /// </param>
        /// <param name="predicate">
        ///   Specifies which setups should be verified.
        /// </param>
        /// <param name="error">
        ///   If this setup or any of its inner mock (if present and known) failed verification,
        ///   this <see langword="out"/> parameter will receive a <see cref="MockException"/> describing the verification error(s).
        /// </param>
        /// <returns>
        ///   <see langword="true"/> if verification succeeded without any errors;
        ///   otherwise, <see langword="false"/>.
        /// </returns>
        public bool TryVerify(bool recursive, Func <ISetup, bool> predicate, out MockException error)
        {
            MockException e;

            // verify this setup:
            if (!this.TryVerifySelf(out e) && e.IsVerificationError)
            {
                error = e;
                return(false);
            }

            // optionally verify setups of inner mock (if present and known):
            if (recursive && this.ReturnsInnerMock(out var innerMock) && !innerMock.TryVerify(predicate, out e) && e.IsVerificationError)
            {
                error = MockException.FromInnerMockOf(this, e);
                return(false);
            }

            error = null;
            return(true);
        }
예제 #14
0
파일: Setup.cs 프로젝트: mujdatdinc/moq4
        /// <summary>
        ///   Verifies this setup and those of its inner mock (if present and known).
        /// </summary>
        /// <param name="recursive">
        ///   Specifies whether recursive verification should be performed.
        /// </param>
        /// <param name="predicate">
        ///   Specifies which setups should be verified.
        /// </param>
        /// <param name="verifiedMocks">
        ///   The set of mocks that have already been verified.
        /// </param>
        /// <exception cref="MockException">
        ///   This setup or any of its inner mock (if present and known) failed verification.
        /// </exception>
        internal void Verify(bool recursive, Func <ISetup, bool> predicate, HashSet <Mock> verifiedMocks)
        {
            // verify this setup:
            this.VerifySelf();

            // optionally verify setups of inner mock (if present and known):
            if (recursive)
            {
                try
                {
                    foreach (var innerMock in this.InnerMocks)
                    {
                        innerMock.Verify(predicate, verifiedMocks);
                    }
                }
                catch (MockException error) when(error.IsVerificationError)
                {
                    throw MockException.FromInnerMockOf(this, error);
                }
            }
        }
예제 #15
0
파일: Mock.cs 프로젝트: tomchavakis/moq4
        private bool TryVerifyAll(out MockException error)
        {
            var uninvokedSetups = this.Setups.ToArrayLive(setup => !setup.Invoked);

            if (uninvokedSetups.Length > 0)
            {
                error = MockException.UnmatchedSetups(this, uninvokedSetups);
                return(false);
            }

            foreach (var inner in this.InnerMocks.Values)
            {
                if (!inner.Mock.TryVerifyAll(out error))
                {
                    return(false);
                }
            }

            error = null;
            return(true);
        }
예제 #16
0
파일: Mock.cs 프로젝트: thisismyrobot/moq4
        internal bool TryVerify(Func <ISetup, bool> predicate, HashSet <Mock> verifiedMocks, out MockException error)
        {
            if (verifiedMocks.Add(this) == false)
            {
                // This mock has already been verified; don't verify it again.
                // (We can end up here e.g. when there are loops in the inner mock object graph.)
                error = null;
                return(true);
            }

            foreach (Invocation invocation in this.MutableInvocations)
            {
                invocation.MarkAsVerifiedIfMatchedBy(predicate);
            }

            var errors = new List <MockException>();

            foreach (var setup in this.MutableSetups.ToArray(predicate))
            {
                if (predicate(setup) && !setup.TryVerify(recursive: true, predicate, verifiedMocks, out var e) && e.IsVerificationError)
                {
                    errors.Add(e);
                }
            }

            if (errors.Count > 0)
            {
                error = MockException.Combined(
                    errors,
                    preamble: string.Format(CultureInfo.CurrentCulture, Resources.VerificationErrorsOfMock, this));
                return(false);
            }
            else
            {
                error = null;
                return(true);
            }
        }
예제 #17
0
        private static void VerifyCalls(
            Mock targetMock,
            InvocationShape expectation,
            LambdaExpression expression,
            Times times,
            string failMessage)
        {
            var allInvocations          = targetMock.MutableInvocations.ToArray();
            var matchingInvocations     = allInvocations.Where(expectation.IsMatch).ToArray();
            var matchingInvocationCount = matchingInvocations.Length;

            if (!times.Verify(matchingInvocationCount))
            {
                Setup[] setups;
                if (targetMock.IsDelegateMock)
                {
                    // For delegate mocks, there's no need to compare methods as for regular mocks (below)
                    // since there's only one single method, so include all setups unconditionally.
                    setups = targetMock.Setups.ToArrayLive(s => true);
                }
                else
                {
                    setups = targetMock.Setups.ToArrayLive(oc => AreSameMethod(oc.Expression, expression));
                }
                throw MockException.NoMatchingCalls(failMessage, setups, allInvocations, expression, times, matchingInvocationCount);
            }
            else
            {
                foreach (var matchingInvocation in matchingInvocations)
                {
                    matchingInvocation.MarkAsVerified();
                }
            }

            bool AreSameMethod(LambdaExpression l, LambdaExpression r) =>
            l.Body is MethodCallExpression lc && r.Body is MethodCallExpression rc && lc.Method == rc.Method;
        }
예제 #18
0
        private MockException TryVerifySetups(Func <Setup, MockException> verifySetup)
        {
            var errors = new List <MockException>();

            foreach (var setup in this.Setups.ToArrayLive(_ => true))
            {
                var error = verifySetup(setup);
                if (error?.IsVerificationError == true)
                {
                    errors.Add(error);
                }
            }

            if (errors.Count > 0)
            {
                return(MockException.Combined(
                           errors,
                           preamble: string.Format(CultureInfo.CurrentCulture, Resources.VerificationErrorsOfMock, this)));
            }
            else
            {
                return(null);
            }
        }
예제 #19
0
 protected override bool TryVerifySelf(out MockException error)
 {
     error = null;
     return(true);
 }
예제 #20
0
 protected virtual bool TryVerifySelf(out MockException error)
 {
     error = this.WasMatched ? null : MockException.UnmatchedSetup(this);
     return(error == null);
 }
예제 #21
0
 public override MockException TryVerifyAll()
 {
     return(this.invoked ? null : MockException.UnmatchedSetup(this));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="MockSetupMethodNeverUsedException"/> class. This override of the constructor provides a proper error message to describe the reason for the exception.
 /// </summary>
 /// <param name="innerException">
 /// The inner exception.
 /// </param>
 public MockSetupMethodNeverUsedException(MockException innerException)
     : this(string.Format("Some methods of the mock were setup, but never used.\r\n\r\n{0}", innerException.Message), innerException)
 {
 }