### TestCaseSourceAttribute (NUnit 2.5)

TestCaseSourceAttribute is used on a parameterized test method to identify the property, method or field that will provide the required arguments. The attribute has two public constructors.

    TestCaseSourceAttribute(Type sourceType, string sourceName);
    TestCaseSourceAttribute(string sourceName);

If sourceType is specified, it represents the class that provides the test cases. If not, the class containing the test method is used.

The sourceName argument represents the name of the source used to provide test cases. It has the following characteristics:

- It may be a field, property or method.
- It may be either an instance or a static member.
- It must return an IEnumerable or a type that implements IEnumerable.
- The individual items returned by the enumerator must be compatible with the signature of the method on which the attribute appears. The rules for this are described in the next section.

#### Constructing Test Cases

In constructing tests, NUnit uses each item test case returned by the enumerator as follows:

1. If it is an object[], it is used directly to provide the arguments for the method, as in this example, which returns arguments from a named static field.

       [Test, TestCaseSource("DivideCases")]
       public void DivideTest(int n, int d, int q)
       {
           Assert.AreEqual( q, n / d );
       }

       static object[] DivideCases =
       {
           new object[] { 12, 3, 4 },
           new object[] { 12, 2, 6 },
           new object[] { 12, 4, 3 }
       };

2. If it is an array of some other type, NUnit can use it provided that the arguments to the method are all of that type. For example, the above code could be modified to make the three nested arrays of type int[].

3. If it is a single value type - like numerics or DateTime - it is used directly as the sole argument to the method. The method must, of course take a single argument of the same type for this to work. This eliminates a bit of syntax on the part of the programmer, as in this example:

       static int[] EvenNumbers = new int[] { 2, 4, 6, 8 };

       [Test, TestCaseSource("EvenNumbers")]
       public void TestMethod(int num)
       {
           Assert.IsTrue( num % 2 == 0 );
       }

   Note: Any user-defined struct intended to hold the arguments will be passed directly to the test method, since a struct is a value type. If you intend your user type to be used as described in the following item, you must define it as a class.

4. If it is any other type of object, it is examined using reflection and any public fields or properties with the following names are used:

   Arguments
     An object[] representing the arguments to the method
   Categories
     An IList of categories to be applied to the test case.
   Description
     Sets the description property of the test
   ExpectedException
     Specifies a the Type of an exception that should be thrown by this invocation
   ExpectedExceptionName
     Specifies a the FullName of an exception that should be thrown by this invocation
   Properties
     An IDictionary of properties to be applied to the test case. Note that the values provided must be compatible with PropertiesAttribute. In particular, use of custom types or enums will cause problems.
   Result
     The expected result to be returned from the method, which must have a compatible return type.
   TestName
     Provides a name for the test. If not specified, a name is generated based on the method name and the arguments provided

   Although any object with the required fields or properties may be used, NUnit provides the TestCaseData class for this purpose. The following example returns TestCaseData instances from a data source in a separately defined class.

       [TestFixture]
       public class MyTests
       {
         [Test,TestCaseSource(typeof(MyFactoryClass),"TestCases")]
         public void DivideTest(int n, int d, int q)
         {
           Assert.AreEqual( q, n / d );
         }

         ...
       }

       public class MyFactoryClass
       {
         public static IEnumerable TestCases
         {
           get
           {
             yield return new TestCaseData( 12, 3 ).Returns( 4 );
             yield return new TestCaseData( 12, 2 ).Returns( 6 );
             yield return new TestCaseData( 12, 4 ).Returns( 3 );
             yield return new TestCaseData( 0, 0 )
               .Throws(typeof(DivideByZeroException))
               .SetName("DivideByZero")
               .SetDescription("An exception is expected");
           }
         }
       }

   This example uses the fluent interface supported by TestCaseData to make the program more readable. The last yield statement above is equivalent to

             TestCaseData data = new TestCaseData(0,0);
             data.ExpectedException = typeof(DivideByZeroException;
             data.TestName = "DivideByZero";
             data.Description = "An exception is expected";
             yield return data;

   TestCaseData supports the following properties and methods, which may be appended to an instance in any order.

   .Returns
     The expected result to be returned from the method, which must have a compatible return type.
   .SetCategory(string)
     Applies a category to the test
   .SetProperty(string, string)
   .SetProperty(string, int)
   .SetProperty(string, double)
     Applies a named property and value to the test
   .SetDescription(string)
     Sets the description property of the test
   .SetName(string)
     Provides a name for the test. If not specified, a name is generated based on the method name and the arguments provided
   .Throws(Type)
   .Throws(string)
     Specifies a the Type or FullName of an exception that should be thrown by this invocation

   #### Note

   NUnit locates the test cases at the time the tests are loaded, creates instances of each class with non-static sources and builds a list of tests to be executed. Each source object is only created once at this time and is destroyed after all tests are loaded. In the case of test cases specified within the same class as the tests, a different object is created each time the test is run, so no communication is possible using non-static members of the class.