6

我最近一直在与 Moles 合作,现在我正在转向 Fakes。在我的旧测试项目中,我有一个测试设置,如下所示:

[TestInitialize]
public void Setup()
{
    //...
}

在那里我做了一些必要的设置,就像设置我的一些痣对象一样。

摩尔中的测试方法看起来像那样(还有 [HostType("Moles")] 指定它使用摩尔对象。

[TestMethod]
[HostType("Moles")]
public void MolesTestMethod()
{
    //...
}

现在,在 Fakes 中,他们不再使用 HostType 属性。相反,他们使用 ShimsContext,您可以在其中使用“模拟”类。它看起来像这样:

[TestMethod]
public void FakesTestMethod()
{
    using (ShimsContext.Create())
    {
        //...
    }
}

如果您不使用此上下文,您可能会收到一条错误消息。它基本上说 FakesTestMethod 中有一个 ShimInvalidOperationException,您必须按照下面描述的方式使用 ShimsContext.Create()

-- C#:
using Microsoft.QualityTools.Testing.Fakes;

using(ShimsContext.Create())
{
    // your test code using Shims here
}

-- VisualBasic.NET
Imports Microsoft.QualityTools.Testing.Fakes

Using ShimsContext.Create
    ' your test code using Shims here
End Using  

所以我试图把我的设置调用放到那个上下文中,结果是这样的:

[TestInitialize]
public void Setup()
{
    using(ShimsContext.Create())
    {
        //...
    }
}

现在,如果我在我的 Setup 方法中使用这个上下文,那么在那里完成的所有设置都将在之后用完上下文,并且当单元测试实际上即将运行时将不再有效,这并不是我真正想要的一种测试设置方法。

我通过将 using 放入测试方法本身并在此上下文中和测试代码之前调用私有设置方法来解决此问题。这个 setup 方法现在完成了所有的处理,这在 [TestInitialize] setup 方法之前做了。代码看起来像这样:

[TestMethod]
public void PerformActionFromConfigActionStateActionIdIsSet()
{
    using (ShimsContext.Create())
    {
        Setup();

        //...
    }
}

我现在对这个问题的问题是,这个解决方案完全“扼杀”了 [TestInitialize] 设置方法的想法。我必须将此代码复制到每个测试方法中,最重要的部分是:在此 Setup() 方法中创建的对象将为每个测试创建和销毁,这根本不理想!

有没有其他方法可以在 Fakes 中设置测试数据?任何帮助表示赞赏!

4

2 回答 2

12

使用:

定义一个范围,一个或多个对象将被释放到该范围之外。

您可以通过调用创建 IDisposable 实例,ShimsContext.Create()并使用 using 块对其进行包装。在初始化您的 Fakes 类并离开使用范围后,您的配置将被释放。

我建议创建 IDisposable 实例并在测试结束时手动调用 Dispose。

如果您想避免为每个测试创建上下文,我还建议使用 ClassInitialize 和 ClassCleanup 而不是 TestInitialize 和 TestCleanup,因为它应该足以为所有测试初始化​​一次 Shims。这只有在没有其他依赖项的情况下才有可能(请参阅 Oleg Sych 的回答)。

[TestClass]
public class TestClass1
{
    protected static IDisposable Context { get; set; }

    [ClassInitialize]
    public static void ClassInitialize(TestContext testContext)
    {
        // Create ShimsContext
        Context = ShimsContext.Create();

        // TODO: Additional setup
    }

    [ClassCleanup]
    public static void ClassCleanup()
    {
        Context.Dispose();
        Context = null;
    }

    [TestMethod]
    public void TestMethod1()
    {
        // Fakes should be initialized correctly here
    }

    [TestMethod]
    public void TestMethod2()
    {
        // Fakes should be initialized correctly here
    }
}

希望有帮助。

于 2012-08-30T14:23:36.370 回答
4

使用 ClassInitialize/ClassCleanup 来初始化垫片不是一个好主意。这将使为一种测试方法配置的弯路对类中的所有其他测试方法保持活动状态。换句话说,由 lambdas 捕获的弯路和任何其他状态都将在所有测试方法之间共享。如果您绕过它碰巧使用的方法,这也会破坏测试工具的稳定性。

相反,使用 TestInitialize/TestCleanup 分别为每个测试方法创建/处置 ShimsContext。

于 2012-10-13T00:18:20.670 回答