5

Moq で奇妙な動作が発生しています。特定の方法で動作するようにモック オブジェクトをセットアップし、テストしているオブジェクトでまったく同じ方法でメソッドを呼び出すという事実にもかかわらず、メソッドがあったかのように反応します。呼んだことはありません。

テストしようとしている次のコントローラー アクションがあります。

public ActionResult Search(string query, bool includeAll)
{
    if (query != null)
    {
        var keywords = query.Split(' ');
        return View(repo.SearchForContacts(keywords, includeAll));
    }
    else
    {
        return View();
    }
}

私のユニットテストコード:

public void SearchTestMethod() // Arrange
    var teststring = "Anders Beata";
    var keywords = teststring.Split(' ');
    var includeAll = false;
    var expectedModel = dummyContacts.Where(c => c.Id == 1 || c.Id == 2);
    repository
        .Expect(r => r.SearchForContacts(keywords, includeAll))
        .Returns(expectedModel)
        .Verifiable();

    // Act
    var result = controller.Search(teststring, includeAll) as ViewResult;

    // Assert
    repository.Verify();
    Assert.IsNotNull(result);
    AssertThat.CollectionsAreEqual<Contact>(
        expectedModel, 
        result.ViewData.Model as IEnumerable<Contact>
    );
}

whereAssertThatは、一連のアサーション ヘルパーを備えた単なる独自のクラスです (Assertクラスは拡張メソッドで拡張できないため... ため息...)。

テストを実行すると、次のrepository.Verify()行で失敗しMoqVerificationExceptionます。

テスト メソッド MemberDatabase.Tests.Controllers.ContactsControllerTest.SearchTestMethod()
例外をスローしました: Moq.MockVerificationException: 次の期待が満たされませんでした:
IRepository r => r.SearchForContacts(value(System.String[]), False)

を削除するrepository.Verify()と、コレクション アサートが失敗し、返されたモデルが であることがわかりますnull。私はそれをデバッグしてチェックし、コードが実行query != nullされるブロックの一部に取り込まれていることを確認しました。if問題ありません。

なぜこれが機能しないのですか?

4

1 に答える 1

8

モック リポジトリに渡す配列 ( の結果teststring.Split(' ')) が、 Search メソッドから実際に渡されたもの ( の結果) と同じオブジェクトではないためだと思われますquery.Split(' ')

セットアップ コードの最初の行を次のように置き換えてみてください。

repository.Expect(r => r.SearchForContacts(
    It.Is<String[]>(s => s.SequenceEqual(keywords)), includeAll))

...これは、モックに渡された配列の各要素を配列内の対応する要素と比較しますkeywords

于 2009-08-02T22:42:03.453 に答える