gpt4 book ai didi

rhino-mocks - Rhino Mocks - Stub .Expect 与 .AssertWasCalled

转载 作者:行者123 更新时间:2023-12-03 08:25:35 29 4
gpt4 key购买 nike

好的,我知道 Rhino Mocks 中新的 AAA 语法存在很多混淆,但我必须说实话,从我目前所看到的来看,我喜欢。它读起来更好,并节省了一些击键。

基本上,我正在测试 ListController它基本上将负责一些事情列表:) 我创建了一个最终将成为 DAL 的接口(interface),这当然是暂时的。

我有以下代码:

(manager 是被测系统,data 是 stub 数据接口(interface))

    [Fact]
public void list_count_queries_data()
{
data.Expect(x => x.ListCount(1));
manager.ListCount();
data.VerifyAllExpectations();
}

此测试的主要目的是确保管理器实际上是在查询 DAL。请注意,DAL 实际上并不存在,因此没有“真正的”值(value)回来。

但是,这是失败的,因为我需要将期望更改为具有返回值,例如:

        data.Expect(x => x.ListCount(1)).Return(1);

这将运行良好,测试将通过, 然而 - 让我困惑的是,在这个时间点,返回值意味着 什么都没有 .我可以将其更改为 100、50、42 等等,并且测试将始终通过?

这让我很紧张,因为测试应该是明确的,如果不满足预期的条件应该完全失败,对吧?

如果我将测试更改为(“1”是计数链接到的预期 ID):

    [Fact]
public void list_count_queries_data()
{
manager.ListCount();
data.AssertWasCalled(x => x.ListCount(1));
}

一切顺利,如果我将测试切换到 AssertWasNotCalled ,它按预期失败了..我也认为它读起来好多了,更清楚正在测试的内容,最重要的是按预期通过和失败!

所以, 我在第一个代码示例中遗漏了什么吗? 你对在 stub 上做断言有什么想法? (有一些有趣的讨论 here ,我个人喜欢 this response

最佳答案

你的测试试图达到什么目的?



您正在验证什么行为或状态?具体来说,您是否正在验证协作者(数据)是否拥有其 ListCount方法调用(基于交互的测试),或者你只是想做ListCount返回一个固定值以驱动被测类,同时在其他地方验证结果(基于传统状态的测试)?

如果要设置期望,请使用模拟和期望:
使用MockRepository.CreateMock<IMyInterface>()myMock.Expect(x => x.ListCount())
如果要 stub 方法,请使用 MockRepository.CreateStub<IMyInterface>()myStub.Stub(x => x.ListCount()) .

(除此之外:我知道您可以使用 stub.AssertWasCalled() 来实现与 mock.Expect 大致相同的功能,并且可以使用更好的阅读语法,但我只是在深入研究模拟和 stub 之间的区别)。

Roy Osherove has a very nice explanation of mocks and stubs.

请发布更多代码!

我们需要全面了解您如何创建 stub (或模拟)以及如何将结果用于被测类。是否 ListCount有输入参数吗?如果有,它代表什么?您是否关心它是否以特定值调用?你在乎ListCount返回某个值?

正如 Simon Laroche 指出的那样,如果 Manager 实际上没有对 ListCount 的模拟/ stub 返回值做任何事情,那么测试将不会因此而通过或失败。测试所期望的只是调用了模拟/ stub 方法——仅此而已。

为了更好地理解这个问题,考虑三个信息,你很快就会明白这一点:

  • 正在测试什么
  • 在什么情况下?
  • 预期的结果是什么?

  • 比较:
    基于交互的模拟测试 .模拟电话 考试。

    [Test]
    public void calling_ListCount_calls_ListCount_on_DAL()
    {
    // Arrange
    var dalMock = MockRepository.Mock<IDAL>();
    var dalMock.Expect(x => x.ListCount()).Returns(1);
    var manager = new Manager(dalMock);

    // Act
    manager.ListCount();

    // Assert -- Test is 100% interaction based
    dalMock.VerifyAllExpectations();
    }

    带有 stub 的基于状态的测试 . stub 驱动测试,但不是预期的一部分。

    [Test]
    public void calling_ListCount_returns_same_count_as_DAL()
    {
    // Arrange
    var dalStub = MockRepository.Stub<IDAL>();
    var dalStub.Stub(x => x.ListCount()).Returns(1);
    var manager = new Manager(dalMock);

    // Act
    int listCount = manager.ListCount();

    // Assert -- Test is 100% state based
    Assert.That(listCount, Is.EqualTo(1),
    "count should've been identical to the one returned by the dal!");
    }

    我个人倾向于尽可能基于状态的测试,尽管使用 Tell, Don't Ask 设计的 API 通常需要基于交互的测试。请记住,因为您不会有任何暴露的状态来验证!

    API 困惑。模拟不是 stub 。还是他们?

    rhino mocks 中的 mock 和 stub 之间的区别是困惑的。传统上, stub 并不意味着有期望——所以如果你的测试替身没有调用它的方法,这不会直接导致测试失败。

    ... 然而,Rhino Mocks API 功能强大,但令人困惑,因为它让您对 stub 设定期望,对我来说,这与公认的术语背道而驰。我也不在意这些术语。在我看来,如果消除这种区别并且在测试中调用的方法可以起到双重作用,那就更好了。

    关于rhino-mocks - Rhino Mocks - Stub .Expect 与 .AssertWasCalled,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/477924/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com