Unit Tests and Generics

The generation of unit tests for generic types and generic methods has limitations. For example, although generated unit tests can test methods that take generic instances as parameters, they cannot test fully generic methods or classes. This topic describes those limitations.

Generic Methods

The following is an example of a generic method. T is an unbound type.

void Method1(List<T> list) {}

Visual Studio cannot generate a unit test for a method or property that uses an unbound type. However, Visual Studio will generate a commented-out approximation of an appropriate unit test for the method. This test will include a //To-do statement that advises you how to change the test to make it work.

Non-Public Generic Types

Visual Studio cannot create private accessors for generics in any form. Therefore, if a generic type is non-public, Visual Studio cannot generate a unit test for it. However, Visual Studio can generate a unit test for a non-public method that takes a generic as a parameter, as long as that generic is a public type.  

Examples

In the following code, MyGeneric<> is internal, and therefore non-public to the test project.

internal class MyGeneric<T>
{
    public MyGeneric(T t) { m_t = t; }
    public T GetIt() { return m_t; }
    private T m_t;
}

public class MyClass
{
    internal int Sample(MyGeneric<int> x) { return x.GetIt(); }

    private MyGeneric<long> m_myLong;
}

The preceding code illustrates three limitations:

  • A test for MyGeneric<T>.GetIt() fails because a private accessor to MyGeneric<T> cannot be generated.

  • A test for MyClass.Sample() also fails because a private accessor cannot be generated. Because the generic cannot be mapped to a private accessor, the test engine has no way to treat the parameter x because it cannot access a specific instance of MyGeneric<T>.

  • If you generate a private accessor for MyClass, no accessor will be created for the field m_myLong because a private accessor cannot be generated for MyGeneric<T>. Without the private accessor, you cannot access a specific instance.

Methods That Take a Generic Instance

The following is an example of a method that takes a generic instance as a parameter. It has fully bound types.

public void Method2(List<int> list) {}

Visual Studio can generate a unit test for this method, unless List is a non-public type.

Example

To further illustrate the capabilities of unit tests with regard to generics, see the following example:

using System;
using System.Collections.Generic;
using System.Text;

namespace ClassLibrary1
{
    public class Generic<T>
    {
        private T m_t;
        public void SetT(T t)
        {
            m_t = t;
        }
        public T GetT()
        {
            return (m_t);
        }
        public void Test()
        {
            Generic<int> x = new Generic<int>();
        }
    }

    public class Solid
    {
        public T GenericMethod<T>(T t)
        {
            return (t);
        }
        public void UsingGeneric(Generic<int> x)
        {
        }
    }
}

Notes about the preceding code

You can generate unit tests on the class Generic<T> and its contents, but the tests that are generated will contain helpful comments but not useful code. That is, you will have to add code to make them report meaningful test results. The generated tests will contain commented-out statements that you can use as starting points for meaningful test code.

For the class Solid, the unit tests that are generated for GenericMethod<T> will contain mostly comments that advise you where to add code.

See Also

Concepts

Unit Tests Overview

Other Resources

Creating Unit Tests