2017-06-22 11 views
3

私が作成したリポジトリパターンをテストしています。オブジェクトをモックするためにMoqパッケージを使用しています。私は2つのオブジェクトからリファレンスをテストしたかったのですが、結果的に私は驚きました。ここでのテストは、次のとおりです。このケースのAssert.AreSameはtrueを返しますか?

Mock<Repository<Web_Documents>> moqRepo; 
Mock<Repository<Web_Documents>> moqRepo2; 

public void ObjEqGetTest() 
{ 
    //context is DBContext and has been initialized using [TestInitialize] annotation 
    moqRepo = new Mock<Repository<Web_Documents>>(context); 
    moqRepo2 = new Mock<Repository<Web_Documents>>(context); 
    var test = moqRepo.Object.Get(1L); 
    var test2 = moqRepo2.Object.Get(1L); 
    Assert.AreSame(test, test2); 
} 

そして、私のGetメソッドが返す:Expressionビルダーを使用して作成されて

return entities.SingleOrDefault(predicate) 

predicate(必要であれば、私は、コードを追加することができます)。

なぜAssertがtrueを返すのですか?2つの異なるオブジェクトを作成したときはどうなりますか?

Getメソッドは、DBからデータをフェッチするたびに(同じモデルが使用されているモデルを指しているので)同じ参照を返しますか?

ありがとうございました!

EDIT @CodeCasterは、私が作成した要求では、Mocking reposはnullを返すと述べています。しかし、テーブルWeb_Documentsの値を検証すると、Assertionsがtrueを返します。私はこのことを実証してみましょう:

public void IdExistsGetTest() 
{ 
    moqDoc = new Mock<Repository<Web_Documents>>(context); 
    var testDoc = moqDoc.Object.Get(1L); 
    Assert.AreEqual(testDoc.NomDocument, "Ajouter une catégorie"); 
} 

このテストが成功した、とWeb_Documentsで、ID = 1の行はNomDocument = "Ajouter une catégorie"を持っています。

+0

[ask]を読んで[mcve]を作成してください。また、ユニットテストのためにDbContextに依存してはいけません。テスト中のクラスを模倣することは意味をなさない。あなたは依存関係を模倣する。 test2とtest2は共にnullになります。 – CodeCaster

+1

私は誤った前提で私の答えに基づいて、それを削除しました。私が主張したことは、具体的なクラスを嘲笑するときではなく、インターフェイスを嘲笑するときにのみ当てはまります。私はMoqがそのメソッドが設定されていないときに具体的なクラスを呼び出すとは思わなかった。あなたはまだまったく間違っていますが、答えを編集しようとします。 – CodeCaster

+0

@コードキャスター私は、あなたが言ったことについて質問があります。私の 'リポジトリ'はパラメータとしてDBContextを必要とするので、もし私がコンテキストだけを嘲笑したら、私がそれを作成するときに 'リポジトリ'にDBContextパラメータを与える方法は? –

答えて

4

contextはEntity Frameworkコンテキストであると仮定します。 2つのリポジトリ間で共有するので、異なるリポジトリに対する2つのクエリは同じエンティティを返します。なぜなら、Entity Frameworkはコンテキスト内でエンティティを(特定の意味で)「キャッシュ」するからです。あなたのクエリがすでにコンテキストにアタッチされているエンティティを返した場合(この場合は最初のクエリによって返されます)、同じエンティティを2番目のエンティティに対して再度返します(エンティティは同じプライマリキーを持ち、タイプ)。

2

Evkは戻り値が同じ理由を既に回答しています.DbContextは、同じ主キーの同じインスタンスを返します。

私はあなたのコードについて何か言いたいと思っていました。ここでは:

moqRepo = new Mock<Repository<Web_Documents>>(context); 
moqRepo2 = new Mock<Repository<Web_Documents>>(context); 

あなたはテストしたいクラスを嘲笑しています。テスト中のクラスを嘲笑してはいけません。その依存関係を模倣すべきです。

だから、DbContextを模擬し、あなたの非嘲笑レポにそのを注入:

var contextMock = new Mock<DbContext>(MockBehavior.Strict); 

var repo = new Repository<Web_Documents>(MockBehavior.Strict, contextMock.Object); 
var repo2 = new Repository<Web_Documents>(MockBehavior.Strict, contextMock.Object); 

は今、あなたはあなたが望むものを返すようにcontextMockを設定する必要があります。それはあなたのGet()メソッドによって呼び出される方法と呼ばれるとき。

詳細については、Mocking EF DbContext with Moqを参照してください。

+1

私はこのコードでテストをしましたが、 'Get'がnullを返すか、' context'が決してアクセスされないことは真実ではありません。取得するエンティティを取得し、コンテキストにアクセスし、nullを返しません。 OPがDbContextをモックする必要がありますが、それは本当です。 – Evk

+0

@CodeCasterしかし、私はリポジトリのコンストラクタをAdaptして、 'MockBehavior.Strict'を受け入れる必要がありますか?私はあなたの提案を実装しましたが、MockExceptionが発生し、リポジトリコンストラクタに列挙を追加したにもかかわらず、「すべての呼び出しに対応する設定が必要です」と表示されます。 –

+0

@Leo no、そのパラメータは、モックされたクラスのすべての呼び出しを設定することをMoqに指示します。あなたがそれを望んでいない場合(しかし、すべきです)、インスタンシエーションからそれを削除してください。 – CodeCaster

関連する問題