每个测试的单元测试和模拟

本文关键字:模拟 单元测试 测试 | 更新日期: 2023-09-27 18:34:05

有时在我的测试中,我需要执行不同的 Setup() 调用,为每个测试运行设置不同的模拟 - 如下所示:

private void Setup(bool isTrue)
{
    mock.Setup(x => x.DisplayNames).Returns(new Dictionary<int, string>());
    // ...
    // 5x more of these are the same for all tests
    if (isTrue)
      mock.Setup(x => x.DisplayOld).Returns(isTrue);
      // 5x more of these parameterlized setups 
      ...
}

现在,在我的每个单元测试中,我都会调用 Setup(true/false)。

由于单元测试是并行运行的(默认情况下为 xUnit),这会导致任何锁定问题吗?(假设两个测试同时调用 Setup()。

如果是这种情况:

  1. 如何纠正这种情况?
  2. 如果想要一个传递参数的单一方法(如 setup()) - 对于不同的模拟场景,正确的方法是什么?

每个测试的单元测试和模拟

查看有关测试上下文模式的文章。您可以将模拟作为局部变量,并在测试上下文类中自定义其设置。然后,并行运行它们是安全的。我在 Java 中使用 JUnit+Mockito 和 .Net 中的 NUnit/MSTest+Moq 使用这种模式。

您需要使用参数化的单元测试。可以使用 xUnit 测试框架的内联数据属性。在这种情况下,不需要在设置方法中设置模拟。可以直接在实际测试方法中设置。您的测试方法如下所示

[Theory]
[InlineData(false)]
[InlineData(true)]
public void SampleTest(bool flag)
{
    .... //do any set up operations
    .... //Assert logic to verify
}

测试框架将根据您使用 InlineData 属性提供的输入在运行时生成尽可能多的测试方法。由于测试方法在运行时被拆分为单独的方法,因此您不会遇到任何锁定或线程问题。