TestCase attribute does not play well with variadic test functions

Bug #908829 reported by Konstantin Khomoutov
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
NUnit Framework
Fix Released
High
Charlie Poole
NUnit V2
Fix Released
Medium
Charlie Poole

Bug Description

I often have a need to test something which produces an array of an arbitrary number of elements and it's handy to embed the "reference array" (an array of expected values) directly into a TestCase attribute, like this:

[TestCase("a-b-c", '-', "a", "b", "c")]
public void TestStringSplit(String s, Char sep, params String[] expected)
{
  Assert.IsEqual(s.Split(sep), expected);
}

The problem is that if such a reference array consists of exactly one element, NUnit machinery fails to reconcile its type with the matching variadic argument of the test function even though in C# it's perfectly OK to call a function declared as
void Foo(params String[] args);
with just one actual argument, like
Foo("xyzzy");

To demonstrate, the test code

using System;
using NUnit.Framework;

[TestFixture]
public class DoTests
{

 [TestCase("foo", "bar", "baz")]
 [TestCase("foo", "bar", "baz", "xyzzy")]
 [TestCase("foo", "bar")]
 public void Test(String a, params String[] args)
 {
  Assert.IsTrue(true);
 }
}

runs the first two tests OK and then fails on the third with

ProcessModel: Default DomainUsage: Single
Execution Runtime: Default
...F
Tests run: 3, Errors: 1, Failures: 0, Inconclusive: 0, Time: 0,0468765 seconds
  Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0

Errors and Failures:
1) Test Error : DoTests.Test("foo","bar")
   System.ArgumentException : Невозможно преобразовать объект типа "System.String" к типу "System.String[]".
   в System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   в System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   в System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   в System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   в System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   в NUnit.Core.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
   в NUnit.Core.TestMethod.RunTestMethod(TestResult testResult)
   в NUnit.Core.TestMethod.RunTestCase(TestResult testResult)

Unfortunately, I have Russian locale here but the error message roughly translates as:
System.ArgumentException : Cannot convert object of the type "System.String" to the type "System.String[]".

I'm not sure, but may be it's possible to know from the reflection info that the matching argument is declared to be variadic and convert the actual argument to an array of the matching type?

Related branches

Changed in nunitv2:
status: New → Triaged
importance: Undecided → Medium
assignee: nobody → Charlie Poole (charlie.poole)
milestone: none → 2.6.0
Changed in nunitv2:
status: Triaged → Fix Committed
Changed in nunit-3.0:
status: New → Triaged
importance: Undecided → High
assignee: nobody → Charlie Poole (charlie.poole)
milestone: none → 2.9.6
Changed in nunit-3.0:
status: Triaged → Fix Committed
Changed in nunitv2:
status: Fix Committed → Fix Released
Changed in nunit-3.0:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.