2012-02-13 14 views
2

私は次のコードを持っていますので、単体テストを書くのに助けが必要です。私はMoqライブラリを使用しています。Moq - どのパラメータを清掃したメソッド呼び出しを確認するか(リスト)

ここでは取引があります。私はリポジトリ(インターフェイス)への依存関係を持つビジネスクラスを持っているので、それを使ってエンティティをデータベースに保存することができます。私のエンティティは基本的に文字列のリストです。 MyBusinessClassのAddAndSaveメソッドは、パラメータとして受け取った値を取得し、リストに入れ、IRepositoryからSaveメソッドを呼び出します。次に、私は自分のエンティティのリストをクリアします。下のコードはこの例を示しています(ここでは簡単に説明しました)。

ユニットテストもあります。

using System.Collections.Generic; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using Moq; 

namespace TestesGerais 
{ 
    public class MyEntity 
    { 
     public MyEntity() 
     { 
      MyList = new List<string>(); 
     } 
     public List<string> MyList { get; set; } 
    } 

    public interface IRepository 
    { 
     void Save(MyEntity entity); 
    } 

    public class MyBusinessClass 
    { 
     public IRepository Repository { get; set; } 
     private MyEntity _entity = new MyEntity(); 
     public void AddAndSave(string info) 
     { 
      _entity.MyList.Add(info); 
      Repository.Save(_entity); 
      _entity.MyList.Clear(); // for some reason I need to clear it 
     } 
    } 

    [TestClass] 
    public class UnitTest10 
    { 
     [TestMethod] 
     public void TestMethod1() 
     { 
      var mock = new Mock<IRepository>(); 
      MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object }; 
      b.AddAndSave("xpto"); 
      mock.Verify(m => m.Save(It.Is<MyEntity>(x => x.MyList[0] == "xpto")), Times.Exactly(1)); 
     } 
    } 
} 

IRepositoryの保存方法は、そのパラメータ(実体)は、リスト内の1つの要素を持っており、この要素に値「xpto」を有すると呼ばれていた場合は私のユニットテストチェック。 System.ArgumentOutOfRangeExceptionが:

私はこのテストを実行すると、それはエラーメッセージを赤に変わり、「試験方法TestesGerais.UnitTest10.TestMethod1は例外をスローしたインデックスが範囲外であったサイズより非負未満でなければなりません。コレクション。 パラメータ名:インデックス "。

[OK]これは、清掃されたリストによって引き起こされます。私が "_entity.MyList.Clear();"という行にコメントすると、すべてうまく行きます。

質問:私のビジネスクラスの "Clear"行にコメントを付けずに、特定の値(値 "xpto"を持つ1つの要素を持つエンティティ)を渡してリポジトリのメソッドが呼び出されていることを確認するにはどうすればよいですか?

ありがとうございました

答えて

1

Moqのコールバック機能を使用して単体テストを変更しました。このようにして、私はモックをセットアップして、AddAndSaveが呼び出されたときに受け取るパラメータをユニットテストの変数に保存し、後でそれをアサートすることができます。あなたの提案、アントニーが、方法AddAndSaveため

[TestMethod] 
    public void TestMethod1() 
    { 
     var mock = new Mock<IRepository>(); 
     string result = string.Empty; 
     mock.Setup(m => m.Save(It.IsAny<MyEntity>())).Callback((MyEntity e) => { result = e.MyList[0]; }); 
     MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object }; 
     b.AddAndSave("xpto"); 
     Assert.AreEqual(result, "xpto"); 
    } 
+0

+1すてきな解決策 –

0

あなたのメソッドを分割することができます。 "AddAndSave"はそれだけではありません。追加と保存のビットの動作を単独でテストすることができます。

+0

おかげで私は今壊したくなかった契約であり、私はその機能をテストする必要があります。しかし、私はこの場合Moqを動作させるためのトリックを得ました。ここでそれを説明します。 – Fabio

関連する問題