6

私は最近Molesと仕事をしていて、今はFakesに切り替えています。以前のテストプロジェクトでは、次のようなテストセットアップがありました。

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

そこでは、ほくろオブジェクトのいくつかをセットアップするのと同じように、いくつかの必要なセットアップを行いました。

ほくろのテストメソッドは、どういうわけかそのように見えました([HostType( "Moles")]も、ほくろオブジェクトを使用することを指定しています。

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

現在、偽物では、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())
    {
        //...
    }
}

さて、セットアップメソッドでこのコンテキストを使用すると、そこで行われるすべてのセットアップは後でコンテキストを使い果たし、単体テストが実際に実行されようとしているときに無効になります。これは実際には私が望んでいることではありません。テストのセットアップ方法。

この問題を修正するには、usingをテストメソッド自体の内部に配置し、このコンテキスト内でテストコードの前にプライベートセットアップメソッドを呼び出すだけです。このセットアップメソッドは、[TestInitialize]セットアップメソッドの前に実行されていたすべての処理を実行するようになりました。コードはどういうわけか次のようになります。

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

        //...
    }
}

この問題に関する私の問題は、このソリューションが[TestInitialize]セットアップメソッドのアイデアを完全に「殺す」ことです。このコードを各テストメソッドと最も重要な部分に複製する必要があります。このSetup()メソッドで作成されたオブジェクトは、各テストで作成および破棄されますが、これはまったく理想的ではありません。

偽物でテストデータを設定する他の方法はありますか?どんな助けでも大歓迎です!

4

2 に答える 2

12

使用:

1 つまたは複数のオブジェクトが破棄される範囲外のスコープを定義します。

呼び出して IDisposable インスタンスを作成し、ShimsContext.Create()それを using ブロックでラップします。Fakes クラスを初期化し、using スコープを離れると、構成が破棄されます。

IDisposable インスタンスを作成し、テストの最後に手動で Dispose を呼び出すことをお勧めします。

テストごとにコンテキストの作成を避けたい場合は、すべてのテストで Shim を 1 回初期化するだけで十分なため、TestInitialize と TestCleanup の代わりに ClassInitialize と ClassCleanup を使用することもお勧めします。これは、追加の依存関係がない場合にのみ可能です (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 を使用してシムを初期化することはお勧めできません。これにより、1 つのテスト メソッドに対して構成された迂回路が、クラス内の他のすべてのテスト メソッドに対してアクティブなままになります。つまり、回り道とラムダによってキャプチャされた追加の状態は、すべてのテスト メソッド間で共有されます。また、たまたま使用しているメソッドを迂回すると、テスト ハーネスが不安定になる可能性があります。

代わりに、TestInitialize/TestCleanup を使用して、各テスト メソッドの ShimsContext を個別に作成/破棄します。

于 2012-10-13T00:18:20.670 に答える