Search code examples
c#asp.net-mvcvisual-studiovs-unit-testing-framework

Unit test not recognized if i add a generic constrain to the class


I want to add a generic constraint to my unit test class

public class CacheOperationsUnitTests<T>
{
    private ITCache<T> ICacheStore;
    static readonly IUnityContainer container = new UnityContainer();
    static CacheOperationsUnitTests()
    {
        container.RegisterType(typeof(ITCache<>), typeof(TRedisCacheStore<>), (new ContainerControlledLifetimeManager()));
    }

    public CacheOperationsUnitTests()
    {
        ICacheStore = container.Resolve<TRedisCacheStore<T>>();

    }

But when I do so, my unit tests are not recognized in the Test Explorer and when I try to run the unit test I get to see this below:

No test is available in F:\projects\Development VSTO\TRF Dev ( Performance ) New\Perf\SSRProd\Caching.UnitTests\bin\Debug\Caching.UnitTests.dll. Make sure that test discoverer & executors are registered and platform & framework version settings are appropriate and try again.**

Works fine when I remove the <T> from the class name but I need <T> because I need them in my code:

private ITCache<T> ICacheStore;

Solution

  • It isn't a generic constraint that is hurting you; a generic constraint is the "where T : SomeWhatever" part - you don't have that. What is hurting you here is the addition of a generic type parameter - i.e. being generic itself.

    Imagine you're a test runner. You can see a

    public class SomeTests<T> {}
    

    that has public methods that look like tests. Now; how do you create an instance of that? What T do you choose? You can't create an instance of an open generic type - you need a concrete type, like SomeTests<Bar> (for some type Bar).

    One option might be to have:

    public abstract class CacheOperationsUnitTests<T>
    public class FooCacheOperationsUnitTests : CacheOperationsUnitTests<Foo>
    public class BarCacheOperationsUnitTests : CacheOperationsUnitTests<Bar>
    // plus whatever other T you need
    

    However, I strongly suspect you can simply remove the generics from your test, and use a specific concrete type in place of T.