对模拟对象的期望似乎没有得到满足(最小起订量)

发布于 2024-07-29 17:13:16 字数 1760 浏览 4 评论 0原文

我在 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 code> 类无法使用扩展方法进行扩展...叹息...)。

当我运行测试时,它在 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 块部分。 那里没有问题。

为什么这不起作用?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不奢求什么 2024-08-05 17:13:16

我怀疑这是因为您传递到模拟存储库的数组(teststring.Split(' ') 的结果)与实际从 Search 方法传入的对象不是同一对象(query.Split(' ') 的结果)。

尝试将设置代码的第一行替换为:

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

... 这会将传递给模拟的数组的每个元素与 keywords 数组中的相应元素进行比较。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文