对Mock对象的期望似乎没有得到满足(Moq)

时间:2009-08-02 22:17:23

标签: unit-testing moq expect

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

其中AssertThat只是我自己的一类,有一堆断言助手(因为Assert类不能用扩展方法扩展...叹息......)。

当我运行测试时,repository.Verify()行失败,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)

如果我删除repository.Verify(),则集合断言无法告诉我返回的模型是null。我已经调试并检查了query != null,并且我被带入运行代码的if块的一部分。没问题。

为什么这不起作用?

1 个答案:

答案 0 :(得分:7)

我怀疑这是因为您传递到模拟存储库的数组(teststring.Split(' ')的结果)与实际从搜索方法传入的数组不同({{{{1}的结果1}})。

尝试使用以下代码替换设置代码的第一行:

query.Split(' ')

...它将传递给你的mock的数组的每个元素与repository.Expect(r => r.SearchForContacts( It.Is<String[]>(s => s.SequenceEqual(keywords)), includeAll)) 数组中的相应元素进行比较。