Expectation on Mock Object doesn't seem to be met (Moq)

感情迁移 提交于 2019-12-10 15:20:04

问题


I'm experiencing some odd behavior in Moq - despite the fact that I setup a mock object to act a certain way, and then call the method in the exact same way in the object I'm testing, it reacts as if the method was never called.

I have the following controller action that I'm trying to test:

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

My unit test code:

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>
    );
}

where AssertThat is just a class of my own with a bunch of assertion helpers (since the Assert class can't be extended with extension methods... sigh...).

When I run the test, it fails on the repository.Verify() line, with a MoqVerificationException:

Test method MemberDatabase.Tests.Controllers.ContactsControllerTest.SearchTestMethod()
threw exception:  Moq.MockVerificationException: The following expectations were not met:
IRepository r => r.SearchForContacts(value(System.String[]), False)

If I remove repository.Verify(), the collection assert fails telling me that the model returned is null. I have debugged and checked that query != null, and that I am taken into the part of the if block where the code is run. No problems there.

Why doesn't this work?


回答1:


I suspect it's because the array you're passing into your mocked repository (the result of teststring.Split(' ')) is not the same object as the one that actually gets passed in from the Search method (the result of query.Split(' ')).

Try replacing the first line of your setup code with:

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

... which will compare each element of the array passed to your mock with the corresponding element in the keywords array.



来源:https://stackoverflow.com/questions/1220013/expectation-on-mock-object-doesnt-seem-to-be-met-moq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!