c# - xUnit 测试因共享静态数据而失败

标签 c# unit-testing xunit

我有几个使用一些静态类的单元测试,例如:

public static class Utility
{
    private static Data data;

    public static void Init(Data data)
    {
        this.data = data;
    }

    public static void Process()
    {
        // Some actions that changes this.data (not reference, just inner Values)
    }
}

public class Data
{
    public List<string> Values { get; set; }

    public void Add(string value)
    {
        Values.Add(value);
    }
}

每个单元测试都会初始化 Data 实例并将其传递给 Utility:

[Fact]
public void UnitTest1()
{
    var data = new Data();
    data.Add("val1");
    Utility.Init(data);

    Utility.Process();

    // check changed data instance
}

[Fact]
public void UnitTest2()
{
    var data = new Data();
    data.Add("another_val1");
    data.Add("another_val2");
    Utility.Init(data);

    Utility.Process();

    // check changed data instance
}

如果我单独运行每个测试,那么就没有问题 - 没有失败的测试。 但是,如果我按顺序运行测试,则其中一个单元测试会失败,因为尽管有 Utility.Init 调用,Utility.data 仍包含先前测试的实例(短时间内)。 如果我通过命令行运行测试(测试执行得非常快),那么大部分测试很可能会因为同样的原因而失败。我该如何解决这个问题?

最佳答案

由于静态实用程序的性质,所有测试都访问共享静态资源,这可能会产生负面影响(正如已经经验到的那样)。我建议将实用程序类作为实例类

public class Utility
{
    private Data data;

    public Utility(Data data) {
        this.data = data;
    }

    public void Process() {
        // Some actions that changes this.data (not reference, just inner Values)
    }
}

示例测试如下

[Fact]
public void UnitTest1() {
    //Arrrange
    var data = new Data();
    data.Add("val1");
    var subject = new Utility(data);

    //Act
    subject.Process();

    //Assert
    // check changed data instance
}

我怀疑 initil 问题是 XY problem并且该实用程序还被用作生产中的静态依赖项,这是一种代码味道。

在这种情况下抽象静态实用程序类

public interface IUtility {
    void Process(Data data);
}

并重构实现

public class Utility : IUtility {

    public void Process(Data data) {
        // Some actions that changes this.data (not reference, just inner Values)
    }
}

这会导致测试看起来像

[Fact]
public void UnitTest1() {
    //Arrrange
    var data = new Data();
    data.Add("val1");
    var subject = new Utility();

    //Act
    subject.Process(data);

    //Assert
    // check changed data instance
}

[Fact]
public void UnitTest2() {
    var data = new Data();
    data.Add("another_val1");
    data.Add("another_val2");
    var subject = new Utility();

    //Act
    subject.Process(data);

    //Assert
    // check changed data instance
}

IUtility 将根据需要注入(inject)到依赖类中,这将使生成的代码更加可靠。

关于c# - xUnit 测试因共享静态数据而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53571123/

相关文章:

moq - xunit 测试中的模拟 HostingEnvironment.QueueBackgroundWorkItem

c# - 无法终止进程 : "No process is associated with this object" error

c# - HttpClient.GetAsync 永远不会在 Xamarin.Android 上返回

c# - 无法在来自 MongoDB 的 LINQ 查询中将字符串转换为 int

c# - 如何从动态加载的程序集中加载包含嵌套类型的泛型类型?

c# - 单元测试 VSTO 项目

xunit - 将对象作为测试参数

unit-testing - 单元测试和数据库

javascript - 我如何使用 Jasmine 通过 id 检查元素是否存在?

c# - 运行 xunit 测试时无法将输出打印到控制台窗口