Description
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
nunit/src/NUnitFramework/framework/Internal/Builders/NUnitTestCaseBuilder.cs
Lines 221 to 229 in db5bee0
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