Skip to content

Better error message for generic test where type parameter cannot be determined #3215

Closed
@mikkelbu

Description

@mikkelbu

This is a corner case that I only ran into in due to work on the analyzers in nunit/nunit.analyzers#54, and my guess is that very few will run into this problem. Nevertheless, I think we could improve the error message, and fix seems simple and safe.

Given a generic test method with no parameters we get a failure that is difficult to interpret for the users (see last example below for more detail). E.g. the test

        [Test]
        public void TestWithGenericTypeThatFailsWithUnusableMessage<T>()
        {
        }

fails with System.InvalidOperationException : Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.

I propose that we change the code at

if (testMethod.Method.IsGenericMethodDefinition && arglist != null)
{
Type[] typeArguments;
if (!new GenericMethodHelper(testMethod.Method.MethodInfo).TryGetTypeArguments(arglist, out typeArguments))
return MarkAsNotRunnable(testMethod, "Unable to determine type arguments for method");
testMethod.Method = testMethod.Method.MakeGenericMethod(typeArguments);
parameters = testMethod.Method.GetParameters();
}
so that we also return MarkAsNotRunnable(testMethod, "Unable to determine type arguments for method") if arglist == null instead of failing hard later on.

Context
The following test is executed without problem, as NUnit determines that int can be used as T.

        [TestCase(1, ExpectedResult = 1)]
        public T TestWithGenericTypeThatWorks<T>(T arg1)
        {
            return arg1;
        }

But if we cannot determine the type of T using the parameters of the method

        [TestCase(1, ExpectedResult = 1)]
        public T TestWithGenericTypeThatFailsWithUsableMessage<T>(int arg1)
        {
            return default(T);
        }

then we mark the test as not runnable with the message Unable to determine type arguments for method.

However, if the method does not have any parameters

        [Test]
        public void TestWithGenericTypeThatFailsWithUnusableMessage<T>()
        {
        }

then we fail with the message System.InvalidOperationException : Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true. and a stacktrace

at System.Reflection.RuntimeMethodInfo.ThrowNoInvokeException()
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at NUnit.Framework.Internal.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args) in C:\src\nunit\nunit\src\NUnitFramework\framework\Internal\Reflect.cs:line 266

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions