← Back to team overview

nunit-core team mailing list archive

[Bug 908829] [NEW] TestCase attribute does not play well with variadic test functions

 

Public bug reported:

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?

** Affects: nunitv2
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of NUnit
Developers, which is subscribed to NUnit V2.
https://bugs.launchpad.net/bugs/908829

Title:
  TestCase attribute does not play well with variadic test functions

Status in NUnit V2 Test Framework:
  New

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?

To manage notifications about this bug go to:
https://bugs.launchpad.net/nunitv2/+bug/908829/+subscriptions


Follow ups

References