NUnit 3.7.1和NOT与[TestFixtureSource]

时间:2017-08-15 18:52:45

标签: unit-testing nunit

抽象背景

我有一个想要覆盖100%的静态有状态类(约束:我无法更改)。它是一个带有静态字段的静态类。我想在状态尚未“设置”的情况下测试静态方法的不同输入。此对象没有可公开访问的机制来更改测试所关注的状态。

  

是的,我知道这是一个非常好的静态测试测试示例。

     

我的问题是,如果没有重构被测单位,我就能明白我是多么聪明。

我无法找到完成此任务的框架方法;我知道我可以为每个测试启动自定义应用程序域以获取我的静态对象的其他“副本”,但是希望避免繁重的开销(特别是如果我要复制某些内容的话)框架可以完成)。

具体示例

考虑以下课程

public class Class1
{
    private static string _state;

    public static string DoStaticStateThing(string thing)
    {
        if(_state == null)
        {
            _state = thing;
        }

        return _state;
    }
}

以及以下测试夹具

using NUnit.Framework;

[TestFixtureSource(nameof(SourceEnumeration))]
public class Class1Tests
{
    private string _testInput;

    static object[] SourceEnumeration =
    {
        new object[] { "foo" },
        new object[] { "bar" }
    };

    public Class1Tests(string input)
    {
        _testInput = input;
    }

    [Test]
    public void TestStatefulThing()
    {
        string result = Class1.DoStaticThing(_testInput);

        Assert.AreEqual(_testInput, result);
    }
}

这导致以下测试结果

1 test passes, 1 test fails due to state; intuitively, I expected both to pass.

我原本期望两个测试都从相同的状态开始,其中_thingnull,但是这个观察结果清楚地表明我正在测试的对象在测试执行之间在内存中存活。

我已经戳了the documentation,发现一个有趣的外观提交,呼叫MultipleDomainTestRunner似乎不再存在,并尝试使用the /domain=Multiple flag,一切都没有运气。

我的问题

  

我能否以某种方式改变Class1Tests TestFixture以实现我想要的:每个测试在有状态对象的相同“起始状态”上执行?

1 个答案:

答案 0 :(得分:1)

NUnit无法做到这一点。使用控制台运行程序(nunit3-console.exe)全部运行时,特定程序集中的测试在同一AppDomain中运行。当NUnit想要在同一进程中在自己的AppDomain中运行每个程序集时,会使用您找到的MultipleDomainTestRunner,因此与您想要执行的操作无关。

鉴于您无法更改正在测试的类,在其中运行每个测试方法自己的AppDomain似乎是一个很好的解决方案。您必须自己提供用于创建AppDomain的基础结构,并且您需要确保在原始AppDomain中没有引用该类本身。这是非平凡的,但通常可以完成。

另一种方法是使用反射来修改静态字段,假设您运行的测试具有足够的权限来执行此操作。您必须确保没有启用任何并行性,以避免多个测试同时更改共享状态。