1

I have a bunch of classes implementing an interface and having a constructor argument.

For this classes i want to write a test with Generic Test Fixture pattern as documented in the nunit docs section: https://docs.nunit.org/articles/nunit/writing-tests/attributes/testfixture.html#generic-test-fixtures

Sample Classes i want to test:

public class ClassToTest: IInterface
{
    public ClassToTest(ConstructorArgument arg1)
    {
        ....
    }
}

class AnotherClassToTest: IInterface
{
    public AnotherClassToTest(ConstructorArgument arg1)
    {
        ....
    }
}

TestClass:

[TestFixture(typeof(ClassToTest))]
[TestFixture(typeof(AnotherClassToTest))]
public class TestClass<TClasses> where TClasses : IInterface, new()
{
    private IInterface _classUnderTest;

    public TestClass()
    {
        ConstructorArgument args = new();
        _classUnderTest = new TClasses(args);  //This will not compile
        //How to Pass constructor argument args?
    }

    [Test]
    public void Test1()
    {
        ...
    }
}

How am i able to pass the necessary constructor arguments to TClasses?

Daimonion
  • 94
  • 8

2 Answers2

2

You could use Activator.CreateInstance for that case.

It should look something like:

_classUnderTest = (TClasses)Activator.CreateInstance(typeof(TClasses), new object[] { args });
Gabriel
  • 226
  • 2
  • 6
  • Thanks a lot. This works. I thought nunit provides a pattern for this. – Daimonion Apr 14 '22 at 14:37
  • 1
    Your two classes under test require a constructor argument. But when you specify `new` in the generic constraint, you are saying that the classes have a default (without args) constructor. Your test can't use new to create an instance of a generic class unless it has a default constructor. – Charlie Apr 14 '22 at 16:27
  • Yep, @Charlie, that is what i experienced after getting this code without compile failures after adding Gabriel's code. i will read the meaning of this new() constraint at class definition time. – Daimonion Apr 19 '22 at 09:19
0

You have already an interface that does abstract every concrete implementation of that - why do you need a generic?

May be like this:

[TestFixture(new ClassToTest(new ConstructorArgument()))]
[TestFixture(new AnotherClassToTest(new ConstructorArgument()))]
public class TestClass
{
    private IInterface _classUnderTest;

    public TestClass(IInterface classUnderTest)
           : _classUnderTest(classUnderTest)
    {}
}
PaulV
  • 11
  • 3