1

I want to test all implementations of an interface with the same test class. I already know the TestCaseSourceAttribute, so I have set it up to load the object instances from the static testObjects array. This code works as I want:

[TestFixture]
public class MySerializerTests
{
    // IStreamSerializers loaded by the TestCaseSource attribute.
    static object[] testObjects = new object[]
    {
        new BinarySerializer(),
        new XmlSerializer(),
        new JsonSerializer()
    };

    [Test, TestCaseSource("testObjects")]
    public void Serialize_NullStreamArgument_ThrowsArgumentException(IStreamSerializer serializer)
    {
        Map map = new Map();
        Assert.Throws<ArgumentNullException>(() => serializer.Serialize(null, map));
    }
}

However, I have to use [TestCaseSource("testObjects")] on every method, which makes it rather tedious for the amount of methods I have. Is there a way of replacing the TextCaseSource attribute with an attribute that works on the whole test class? Maybe similar to the way a parameterized FestFixture works?

I'd like something similar to this, but where I can pass instances of my tested classes via the constructor of the test class:

[TestFixture(0)]
[TestFixture(1)]
[TestFixture(2)]
public class MySerializerTests
{
    // IStreamSerializers loaded by the TestCaseSource attribute.
    static object[] testObjects = new object[]
    {
        new BinarySerializer(),
        new XmlSerializer(),
        new JsonSerializer()
    };

    int currentIndex;

    public MySerializerTests(int index)
    {
        currentIndex = 0;
    }

    [Test]
    public void Serialize_NullStreamArgument_ThrowsArgumentException()
    {
        Map map = new Map();

        Assert.Throws<ArgumentNullException>(() => testObjects[currentIndex].Serialize(null, map));
    }
}
PoLáKoSz
  • 355
  • 1
  • 6
  • 7
Xarbrough
  • 1,393
  • 13
  • 23
  • Can you clarify what you want? The instances are held in a static array, so they are shared among all methods that refer to that array. – Charlie May 23 '16 at 00:29
  • I added a better explanation to the question. My first example already works the way I want, but I am looking for a way to avoid having to use the TestCaseSource attribute on every method. Instead I would like to elegantly create all needed instances via a parameterized TestFixture or a similar way. It works perfectly fine with value types, but I can't pass a constructor call as a parameter. – Xarbrough May 23 '16 at 11:36

1 Answers1

3

You want the TestFixtureSourceAttribute.

[TestFixtureSource("testObjects")]
public class MySerializerTests
{
    // IStreamSerializers loaded by the TestCaseSource attribute.
    static IStreamSerializer[] testObjects = new IStreamSerializer[]
    {
        new BinarySerializer(),
        new XmlSerializer(),
        new JsonSerializer()
    };

    IStreamSerializer _serializer;

    public MySerializerTests(IStreamSerializer serializer)
    {
        _serializer = serializer;
    }

    [Test]
    public void Serialize_NullStreamArgument_ThrowsArgumentException()
    {
        Map map = new Map();
        Assert.Throws<ArgumentNullException>(
            () => _serializer.Serialize(null, map));
    }
}

I haven't compiled this, so you may need to fix typos, etc.

Charlie
  • 12,928
  • 1
  • 27
  • 31
  • After checking the documentation, this looks like the perfect answer. Too bad that I'm using NUnit in Unity, which currently doesn't support the TestFixtureSource attribute; but that's a different problem, so I accept this as the answer and will look if I can update my framework version. – Xarbrough May 24 '16 at 21:04