3

私は TDD を試すつもりであり、そのための適切なツールを研究しています。職場では MS Fakes を使用しているため、変更せずに TDD で MS Fakes を使用しても問題ありません。しかし、私には深刻な問題が 1 つあります。MS Fakes はシナリオで使用することを意図しているように思えます: write code -> write unit test for it。MS Fakes を使用して TDD 中にインターフェイスをモックするにはどうすればよいですか?

たとえば、1つのファイルに次のコードがあります(リファクタリングは後で行われます)

[TestClass]
public class MyTests
{
    [TestMethod]
    public void ShouldReturnSomeResultIfEmptyCollectionOfCustomersWasReturned()
    {
        // arrange
        ICustomerRepository customerRepository = null;
        var targetService = new MyTargetService(customerRepository);

        // act
        int result = targetService.MyMethod();

        // assert
        Assert.AreEqual(1, result);

    }
}

public class MyTargetService : IMyTargetService
{
    private readonly ICustomerRepository customerRepository;

    public MyTargetService(ICustomerRepository customerRepository)
    {
        this.customerRepository = customerRepository;
    }

    public int MyMethod()
    {
        if (customerRepository.GetCustomers().Any())
        {
            return 0;
        }

        return 1;
    }
}

public interface IMyTargetService
{
}

public interface ICustomerRepository
{
    Customer[] GetCustomers();
}

public class Customer
{
}

私の TDD プロセスでは、すべてを 1 つのファイルにまとめてから、これをリファクタリングして別のアセンブリに移動します。しかし、この場所でインラインをモックする必要がありICustomerRepository customerRepository = null;ます。たとえば、NSubstitute を使用すると簡単に実行できます。ただし、MS Fakes を使用する場合は、最初にこのインターフェイスを別のプロジェクトに移動し、単体テストが配置されているプロジェクトからこのプロジェクトを参照して、[Add Fake Assembly] をクリックする必要があります。これは非常に複雑なワークフローのように思われるため、TDD はそれほど迅速かつ効率的ではありません。これらの奇妙な操作をすべて行わずに、次のようなコードを配置したいと思います。

ICustomerRepository customerRepository = new StubBase<ICustomerRepository>
                {
                    GetCustomers = () => Enumerable.Empty<Customer>().ToArray(),
                };

StubBase<>抽象的ですが。それで、MS Fakesでそのようなことをする方法はありますか?

4

3 に答える 3

4

炎上戦争を開始する危険を承知で、これは MS スイートのほとんどのテスト ツールに当てはまります。簡単な回答: これらのツールを使用する場合は、十分な情報に基づいて使用するかどうかを決定する必要があります。「はい」を選択した場合、直感に反しているように見えても、MS の TDD の定義または単体テスト全般に従う必要があります。

  • コード化された UI では、テストの作成を開始する前に、UI のマップを生成する必要があります。これにより、テストのスクリプト作成を開始する前に、UI が完成していることが義務付けられます。
  • MSTest では、同じテスト フィクスチャに属していても、状態を共有できない (作成に費用がかかる) テストを作成する必要があります。これは、テストの独立性や並列性を維持するために、高価なセットアップを何度も実行する必要があることを意味します。
  • PEX により、MS はテスト ケースの自動生成により、既に記述されたコードのテスト カバレッジを約束しました。ただし、TDD とはまったく関係ありません。

MS Fakes では、インターフェイスを含むアセンブリを右クリックして Fakes アセンブリを生成する必要があるようです。次に、命名規則 (私には少し奇妙に思えます) を学び、ラムダ式またはデリゲートを、コードによって実行される可能性のある各インターフェイス メンバーにマップします。結果のテストが読みにくく、リファクタリングに適していないのではないかと心配しています。

依存関係が抽象レイヤー (インターフェース) の背後にあるという推奨されるケースでは、Rhino、Moq、NSubstitute などの通常の疑わしいものは邪魔にならずに正常に動作します。MS Fakes について私が見つけた唯一の場所は、依存関係を分離/挿入するためにソースにアクセスできないレガシー コードまたはサード パーティ コードです。このような場合、MS Fakes が役立つことがあります。

于 2012-11-20T12:45:25.920 に答える
1

Fakes はビルド時のコード生成に依存しており、現在、別のプロジェクトでスタブするインターフェイス/クラスを定義する必要があります。NSubstitute など、実行時にスタブを生成する他のフレームワークと比較すると、これには、新しいテストをコンパイルする前に、追加のリファクタリング手順が 1 つ必要です。つまり、作成したばかりの新しいインターフェイスをテスト プロジェクトからターゲット プロジェクトに移動します。このリファクタリングは、Resharper を使用して数回のキーストロークで実行できます。

于 2012-11-19T16:49:58.697 に答える