维护VS Test Project中单元测试方法之间的上下文

时间:2011-02-12 04:07:58

标签: c# visual-studio unit-testing automated-tests mstest

我想按顺序运行以下单元测试:

  1. 使用随机数创建名称,密码等的新客户。
  2. 检索刚创建的客户并声明其属性包含相同的随机数
  3. 在同一用户上调用ForgotPassword函数,使用相同的用户名随机数
  4. 如清楚所示,我需要生成一次随机数,并在3种测试方法中共享它 我似乎找不到办法做到这一点。

    • 我想过使用TestContext对象,但是为每个实例创建了它。
    • 我尝试使用ClassInitialize()方法没有帮助,因为它是静态的,因此其他方法无法访问该数字。

    知道如何实现我的目标吗?

4 个答案:

答案 0 :(得分:10)

您可以将共享数据放入静态变量吗?

像这样简单:

    private static string testValue = "something";

    [TestMethod]
    public void TestMethod1()
    {
        Assert.AreEqual(testValue, "something");
        testValue = "something2";
    }

    [TestMethod]
    public void TestMethod2()
    {
        Assert.AreEqual(testValue, "something2");
        testValue = "something3";
    }

    [TestMethod]
    public void TestMethod3()
    {
        Assert.AreEqual(testValue, "something3");
    }

更新:总结一下这个问题的其他评论,我认为每个人都完全同意在单元测试之间保持状态是一个坏主意。如果有必要,我的回答只是一种方法。正如我在另一篇评论中所提到的,我过去必须这样做,但不是单元测试。在集成/回归测试之间保持状态有时是有益/必要的,您不一定要模拟对象或隔离应用程序的某些部分。作为软件测试人员,您并不总是具有影响/能力/权限,可以立即重构或重新构建应用程序,使其成为此测试的最佳选择。

答案 1 :(得分:3)

你想要做的是在IRepository接口后面使用类似Repository的东西:

interface IRepository{
    Customer GetCustomer(int id);
}

您可以在代码中实现一个可以查询数据库的真实类,但是在测试中,您可以“模拟”此接口以准确返回您想要的内容。 Moq是我的最爱 - 以下是伪代码,但希望你能得到这个想法:

[Test]
public void Customer_Should_Have_CreateAt_Set_To_Today{
  var mock = new Mock<IRepository>();
  mock.Setup(x => x.GetCustomer(100)).Returns(new Customer{id = 100, Name = "Steve"});

  var Customer = mock.Object;
  Assert.Equal(Customer.CreatedAt,Date.Today);
}

这里的想法是,您完全控制需要控制的数据,而不依赖于实例化对象等。

答案 2 :(得分:2)

运行共享上下文的单元测试是一个非常糟糕的主意。虽然我对建议持开放态度,但我从来没有想过按照你的建议行事。

如果有人以不同的顺序或孤立地运行您的测试,那么它们将会失败。像这样的测试被称为 flakey - 它们有时会通过,但不会通过其他测试 - 目前尚不清楚原因。

使用像Rhino Mocks之类的模拟框架来实例化所需状态中的模拟依赖项要好得多。这样,每个测试都是一个独立的测试,可以在不参考任何其他测试的情况下验证特定事物。

您会发现维持这样的测试要容易得多,并且结果中的误报和否定数量会减少。

答案 3 :(得分:0)

使用依赖项构建单元测试是一种糟糕的形式。但是,使用依赖项构建功能性测试并不是一种糟糕的形式。实际上,在任何具有正常复杂程度的应用程序中几乎都需要它。

您要做的不是单元测试。这是一个功能测试。并且您确实需要在测试方法之间使用共享值来从用户的角度来完成事情。