4

単体テストで使用できるモッカブルを作成することを検討していDataContextます。1 つのアプローチをここで説明します。ただし、このアプローチの問題は、リポジトリへの変更がすぐに有効になることCommitですSubmitChanges

反対に、正しいSubmitChanges動作を含めるには、 からの多くの複雑なコードの複製が必要になりDataContext、さらに多くのバグが発生する可能性があります。

モック化されたメモリ内リポジトリ (を待たないSubmitChanges) の単純な実装は、単体テストで使用できますか? これは通常どのように行われますか?

4

3 に答える 3

4

私の理解が正しければ、あなたは SUT (Subject Under Test) を完全には特定していません。

  • データベースとの接続をテストする場合は、統合テストについて話しているため、モックを作成しないでください。DataContext

  • を呼び出すロジックをテストする場合はDataContext、単体テストです

いずれにせよ、への呼び出しをDataContextリポジトリにラップすることをお勧めします。リポジトリはデータベースとの通信を担当します。このアプローチに従うと、作業が簡単になります。

例でそれを明確にし、最後に、テスト可能なコードを書くのに役立ついくつかのリンクをお勧めします. (私はいつもこれを言いますが、もう一度言います。テストを書くのは簡単です。真の努力は、クリーンでテスト可能なコードを書くことに費やされなければなりません)

public interface IMyRepository
{
   void ChangeEmail(int employeeId, string newEmail);
}
public class MyRepository : IMyRepository
{
   private MyDataContext context;
   public MyRepository(MyDataContext context)
   {
      this.context = context;
   }
   public void ChangeEmail(int employeeId, string newEmail)
   {
      //save your email using your context
   }
}

ここで、コンシューマー コードにリポジトリを挿入します。

public class MyCommand
{
   public MyCommand(IMyRepository myRepository)
   ...
   public void ChangeEmail(int employeeId, string newEmail)
   {
      //adding condition just to clarify how to test
      if(this.AllowChangeEmail(employeeId))
      {
         this.myRepository.ChangeEmail(employeeId, newEmail);
      }
      else
      {
         throw new DomainException("this should not happen");
      }
   }
   ...
}

の使用を分離しましたDataContext。ドメイン コードの観点からは、DataContextは存在しません。ドメインが認識している唯一のコードは です。IMyRepositoryこれはインターフェイスであるため、ドメインをリファクタリングすることなく、アプリケーションの動作を変更するプロバイダを簡単に変更できます。コード

まだテストについて話していないことに気がついたら、なぜですか? 私が言ったように、最初にすべきことは、クリーンでテスト可能なコードを書くことです (誤解しないでください。TDD に従う必要があります。つまり、テストを最初に作成する必要があります。私はデモとしてこのアプローチに従っています)。このコードがあれば、アプリケーションのロジックをテストするのがいかに簡単か見てみましょう。明確にするために手動でスタブを作成しますが、実際のコードでは、 AutoFixtureFluentAssertions、およびMoqIMyRepositoryなどのツールを使用して、代わりに自動モック オブジェクトを使用する必要があります。

public class MyFakeProvider : IMyRepository
{
   public void ChangeEmail(int employeeId, string newEmail)
   {
      //write some assert here indicating the method was called
   }
}

[Test]
public void MyTest()
{
   var myMock = new MyFakeProvider();
   var sut = new MyCommand(myMock);

   sut.Invoking(x => x.ChangeEmail(3, "my@email.com")).ShouldNotThrow();
}

これらのリンクは、テスト可能なコードを書く:

http://misko.hevery.com/code-reviewers-guide/

http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf

http://misko.hevery.com/presentations/

http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded

http://www.youtube.com/watch?v=RlfLCWKxHJ0&feature=player_embedded

http://www.youtube.com/watch?v=-FRm3VPhseI&feature=player_embedded

http://www.youtube.com/watch?v=4F72VULWFvc&feature=player_embedded

于 2012-04-30T04:02:55.970 に答える
2

テスト対象のクラス/コンポーネントは何ですか? リポジトリを直接テストするのではなく、リポジトリを消費するものだけをテストする場合、モックは必要に応じて基本的なものにすることができます。

ただし、コンポーネントとリポジトリの間でエンドツーエンドの統合テストを実行したい場合は、別のアプローチが必要になります。テスト データベースに対して実行します。

于 2012-04-30T01:55:08.013 に答える
1

SubmitChanges、InsertOnSubmit などを含むリポジトリを表すインターフェイスを作成しました。DataContext が実装するもの。また、テーブルの IQueryable プロパティ。その後、DataContext サブクラスでこのインターフェイスを実装できるので、何もする必要はありません。単体テストでは、モックを作成するだけで、IQueryables を模倣して Lists を作成し、AsQueryable メソッドを使用できます。

于 2012-04-30T02:09:41.557 に答える