将Nunit与TestCaseSource一起使用 - 多次运行会更改结果

时间:2014-03-10 10:17:20

标签: c# nunit

我正在使用Nunit为C#项目编写单元测试。

我正在尝试使用TestCaseSource属性使用不同的数据多次运行单个测试。

我在其他地方这样做没有任何问题,但现在我发现我第一次运行我的测试,代码通过。下一次,它没有。使用一些Console.WriteLine语句,我可以看到测试数据每次都不同。

用于生成数据的方法是测试类的内部方法,不是静态的,并且每次测试都会从头开始生成所有必需的依赖项。

-

我有一个假类,它保存一个值队列,以便在调用给定函数时返回。为每个测试创建一个新类。

但是,如果第一次运行测试,它会耗尽队列,下次运行时,不会找到任何数据。当然这应该每次都重新生成?

-

每次运行测试时,就好像Nunit没有调用TestCaseSource属性指定的方法 - 只有在首次加载项目时。

这是预期的吗?有解决方法吗?

编辑:

好的,这是一个非常基本的例子,如下:

[TestFixture]
public class Tests
{
    public interface IEntry
    {
        object Read();
    }

    [TestCaseSource("TestData")]
    public void Test(Mock<IEntry> entry)
    {
        object o = entry.Object.Read();
        object o2 = entry.Object.Read();
    }

    public System.Collections.IEnumerable TestData()
    {
        var entry = new Mock<IEntry>();

        int call = 0;

        entry.Setup(x => x.Read()).Returns(() =>
        {
            Console.WriteLine(call);
            return null;
        }).Callback(() =>
        {
            call++;
        });

        yield return new TestCaseData(entry);
    }
}

如果你在Nunit中观察测试输出,它应该总是显示0,然后是1.在这种情况下,每次运行测试时它都会递增。即第二次运行:2和3,第三次运行:4和5,等等。

如果您将TestData代码移至Test,则每次都会返回正确的值。

1 个答案:

答案 0 :(得分:0)

我假设您正在使用NUnit GUI运行器?

您所看到的是(我相信,我在NUnit源代码中无法轻易找到确认信息)是对测试运行器的优化。不是在每次测试运行时重新创建TestCaseSource属性提供的值,而是在测试中的程序集发生更改时才会这样做。

如果您更改代码以删除Moq依赖项,则会更清楚:

[TestFixture]
public class SampleTests
{
    [TestCaseSource("TestData")]
    public void Test(CallTracker callTracker)
    {
        callTracker.Call++;
        callTracker.Call++;
    }

    public IEnumerable TestData()
    {
        yield return new TestCaseData(new CallTracker());
    }

    public class CallTracker
    {
        int call;

        public int Call
        {
            get
            {
                return call;
            }
            set
            {
                call = value;
                Console.WriteLine(call);
            }
        }
    }
}

这会产生与代码相同的行为。每当评估CallTracker时,TestCaseSource都会重新创建,但由于调用计数不断增加,测试运行器必须重新生成相同的实例(因为我假设是性能原因)。

Visual Studio 中的Resharper测试运行器不会出现此行为;它总是显示12重复运行而不重新编译。这可能是为什么开始运行测试比NUnit GUI运行器慢的原因。同样,NUnit控制台不会出现这种行为,因为它总是冷却。