针对不同的接口实现减少NUnit测试中的重复

问题描述 投票:2回答:2

我有以下界面:

public interface IStack
{
    int Peek();
    void Push(int i);
}

两个实现:

public class LinkedListStack : IStack
{
    public void Push(int x)
    {
     ...
    }

    public int Peek()
    {
     ...
    }
}

public class ArrayStack : IStack
{
    public void Push(int i)
    {
     ...
    }

    public int Peek()
    {
     ...
    }
}

对于我的单元测试 - 我目前有这样的东西,两个文件包含相同的测试 - 唯一的区别是实现:

LinkedListStackTest.cs:

public class LinkedListStackTest
{
    [Test]
    public void PushToStack()
    {
        //Arrange
        IStack stack = new LinkedListStack();

        //Act
        stack.Push(1);

        //Assert
        Assert.AreEqual(1, stack.Peek());
    }
}

ArrayStackTest.cs

public class ArrayStackTest
{
    [Test]
    public void PushToStack()
    {
        //Arrange
        IStack stack = new ArrayStack();

        //Act
        stack.Push(1);

        //Assert
        Assert.AreEqual(1, stack.Peek());
    }
}

鉴于实现的测试应该是相同的 - 有没有一种方法可以编写一组NUnit测试,这些测试将针对我的所有IStack实现运行?

c# unit-testing interface nunit
2个回答
2
投票

你可以使用TestCaseSourceAttribute

[Test]
[TestCaseSource(typeof(StackTestCases))]
public void PushToStack(IStack stack)
{
    //Arrange/Act
    stack.Push(1);

    //Assert
    Assert.AreEqual(1, stack.Peek());
}

StackTestCases的实施:

internal class StackTestCases : IEnumerable
{
    public static IEnumerable TestCases
    {
        get
        {
            yield return new TestCaseData(new LinkedListStack());
            yield return new TestCaseData(new ArrayStack());
        }
    }

    /// <inheritdoc />
    public IEnumerator GetEnumerator()
    {
        return TestCases.GetEnumerator();
    }
}

请注意,测试方法将以IStack作为参数:

[Test]
[TestCaseSource(typeof(StackTestCases))]
public void PushToStack(IStack stack)

...你可以在IStackTestCases属性中返回StackTestCases的不同实现:

yield return new TestCaseData(new LinkedListStack());
yield return new TestCaseData(new ArrayStack());

1
投票

为了这个目的,您必须使用具有接口实现的TextFixture属性的泛型。

[TestFixture(typeof(LinkedListStack))]
[TestFixture(typeof(ArrayStack))]
class IStack_Contract<T> where T : IStack, new()
{
}

您只需将类型传递给测试,然后它们将针对各自的实现执行。

© www.soinside.com 2019 - 2024. All rights reserved.