예제 #1
0
        /// <summary>
        /// Verifies that a delegate throws a particular exception when called.
        /// </summary>
        /// <param name="expression">A constraint to be satisfied by the exception</param>
        /// <param name="code">A TestSnippet delegate</param>
        /// <param name="message">The message that will be displayed on failure</param>
        /// <param name="args">Arguments to be used in formatting the message</param>
        public static Exception Throws(IResolveConstraint expression, TestDelegate code, string message, params object[] args)
        {
            Exception caughtException = null;

#if ASYNC
            if (AwaitUtils.IsAsyncVoid(code))
            {
                throw new ArgumentException("'async void' methods are not supported. Please use 'async Task' instead.", nameof(code));
            }
#endif

            using (new TestExecutionContext.IsolatedContext())
            {
                try
                {
                    code();
                }
                catch (Exception ex)
                {
                    caughtException = ex;
                }
            }

            Assert.That(caughtException, expression, message, args);

            return(caughtException);
        }
예제 #2
0
        /// <summary>
        /// Executes the code and returns success if an exception is thrown.
        /// </summary>
        /// <param name="actual">A delegate representing the code to be tested</param>
        /// <returns>True if an exception is thrown, otherwise false</returns>
        public override ConstraintResult ApplyTo <TActual>(TActual actual)
        {
            TestDelegate code            = actual as TestDelegate;
            Exception    caughtException = null;

            if (code != null)
            {
#if ASYNC
                if (AwaitUtils.IsAsyncVoid(code))
                {
                    throw new ArgumentException("'async void' methods are not supported. Please use 'async Task' instead.");
                }
#endif
                try
                {
                    code();
                }
                catch (Exception ex)
                {
                    caughtException = ex;
                }
            }
#if ASYNC
            AsyncTestDelegate asyncCode = actual as AsyncTestDelegate;
            if (asyncCode != null)
            {
                try
                {
                    AwaitUtils.Await(asyncCode, asyncCode.Invoke());
                }
                catch (Exception ex)
                {
                    caughtException = ex;
                }
            }
            if (code == null && asyncCode == null)
#else
            else
#endif
            {
                throw new ArgumentException(string.Format("The actual value must be a TestDelegate or AsyncTestDelegate but was {0}", actual.GetType().Name), "actual");
            }
            return(new ThrowsExceptionConstraintResult(this, caughtException));
        }
예제 #3
0
            internal static Exception Intercept(object invocation)
            {
                var invocationDescriptor = GetInvocationDescriptor(invocation);

#if ASYNC
                if (AwaitUtils.IsAwaitable(invocationDescriptor.Delegate))
                {
                    try
                    {
                        object result = invocationDescriptor.Invoke();
                        AwaitUtils.Await(invocationDescriptor.Delegate, result);
                        return(null);
                    }
                    catch (Exception ex)
                    {
                        return(ex);
                    }
                }

                if (AwaitUtils.IsAsyncVoid(invocationDescriptor.Delegate))
                {
                    throw new ArgumentException("'async void' methods are not supported. Please use 'async Task' instead.");
                }
#endif
                using (new TestExecutionContext.IsolatedContext())
                {
                    try
                    {
                        invocationDescriptor.Invoke();
                        return(null);
                    }
                    catch (Exception ex)
                    {
                        return(ex);
                    }
                }
            }
예제 #4
0
        /// <summary>
        /// Helper method that checks the signature of a TestMethod and
        /// any supplied parameters to determine if the test is valid.
        ///
        /// Currently, NUnitTestMethods are required to be public,
        /// non-abstract methods, either static or instance,
        /// returning void. They may take arguments but the _values must
        /// be provided or the TestMethod is not considered runnable.
        ///
        /// Methods not meeting these criteria will be marked as
        /// non-runnable and the method will return false in that case.
        /// </summary>
        /// <param name="testMethod">The TestMethod to be checked. If it
        /// is found to be non-runnable, it will be modified.</param>
        /// <param name="parms">Parameters to be used for this test, or null</param>
        /// <returns>True if the method signature is valid, false if not</returns>
        /// <remarks>
        /// The return value is no longer used internally, but is retained
        /// for testing purposes.
        /// </remarks>
        private static bool CheckTestMethodSignature(TestMethod testMethod, TestCaseParameters parms)
        {
            if (testMethod.Method.IsAbstract)
            {
                return(MarkAsNotRunnable(testMethod, "Method is abstract"));
            }

            if (!testMethod.Method.IsPublic)
            {
                return(MarkAsNotRunnable(testMethod, "Method is not public"));
            }

            IParameterInfo[] parameters;
            parameters = testMethod.Method.GetParameters();
            int minArgsNeeded = 0;

            foreach (var parameter in parameters)
            {
                // IsOptional is supported since .NET 1.1
                if (!parameter.IsOptional)
                {
                    minArgsNeeded++;
                }
            }

            int maxArgsNeeded = parameters.Length;

            object[] arglist      = null;
            int      argsProvided = 0;

            if (parms != null)
            {
                testMethod.parms    = parms;
                testMethod.RunState = parms.RunState;

                arglist = parms.Arguments;

                if (arglist != null)
                {
                    argsProvided = arglist.Length;
                }

                if (testMethod.RunState != RunState.Runnable)
                {
                    return(false);
                }
            }

            ITypeInfo returnType = testMethod.Method.ReturnType;

#if ASYNC
            if (AwaitUtils.IsAsyncVoid(testMethod.Method.MethodInfo))
            {
                return(MarkAsNotRunnable(testMethod, "Async test method must have non-void return type"));
            }

            if (AwaitUtils.IsAwaitable(testMethod.Method.MethodInfo))
            {
                var resultType = AwaitUtils.GetAwaitableResultType(testMethod.Method.MethodInfo);

                if (parms != null && parms.HasExpectedResult)
                {
                    if (resultType == typeof(void))
                    {
                        return(MarkAsNotRunnable(testMethod,
                                                 "Async test method must not return void when awaited when a result is expected"));
                    }
                }
                else
                {
                    if (resultType != typeof(void))
                    {
                        return(MarkAsNotRunnable(testMethod,
                                                 "Async test method must return void when awaited when no result is expected"));
                    }
                }
            }
            else
#endif
            if (returnType.IsType(typeof(void)))
            {
                if (parms != null && parms.HasExpectedResult)
                {
                    return(MarkAsNotRunnable(testMethod, "Method returning void cannot have an expected result"));
                }
            }
            else if (parms == null || !parms.HasExpectedResult)
            {
                return(MarkAsNotRunnable(testMethod, "Method has non-void return value, but no result is expected"));
            }

            if (argsProvided > 0 && maxArgsNeeded == 0)
            {
                return(MarkAsNotRunnable(testMethod, "Arguments provided for method with no parameters"));
            }

            if (argsProvided == 0 && minArgsNeeded > 0)
            {
                return(MarkAsNotRunnable(testMethod, "No arguments were provided"));
            }

            if (argsProvided < minArgsNeeded)
            {
                return(MarkAsNotRunnable(testMethod, string.Format("Not enough arguments provided, provide at least {0} arguments.", minArgsNeeded)));
            }

            if (argsProvided > maxArgsNeeded)
            {
                return(MarkAsNotRunnable(testMethod, string.Format("Too many arguments provided, provide at most {0} arguments.", maxArgsNeeded)));
            }

            if (testMethod.Method.IsGenericMethodDefinition && arglist != null)
            {
                var typeArguments = new GenericMethodHelper(testMethod.Method.MethodInfo).GetTypeArguments(arglist);
                foreach (Type o in typeArguments)
                {
                    if (o == null || o == TypeHelper.NonmatchingType)
                    {
                        return(MarkAsNotRunnable(testMethod, "Unable to determine type arguments for method"));
                    }
                }


                testMethod.Method = testMethod.Method.MakeGenericMethod(typeArguments);
                parameters        = testMethod.Method.GetParameters();
            }

            if (arglist != null && parameters != null)
            {
                TypeHelper.ConvertArgumentList(arglist, parameters);
            }

            return(true);
        }