代码之家  ›  专栏  ›  技术社区  ›  Christopher Bennage

断言一个方法只被调用一次

  •  28
  • Christopher Bennage  · 技术社区  · 17 年前

    以下是我认为有效的方法:

    [Test]
    public void just_once()
    {
        var key = "id_of_something";
    
        var source = MockRepository.GenerateStub<ISomeDataSource>();
        source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
            .Return(new Something())
            .Repeat.Once();
    
        var client = new Client(soure);
    
        // the first call I expect the client to use the source
        client.GetMeMyThing(key);
    
        // the second call the result should be cached
        // and source is not used
        client.GetMeMyThing(key);
    }
    

    如果第二次调用 GetMeMyThing() 电话 source.GetSomethingThatTakesALotOfResources()

    7 回复  |  直到 9 年前
        1
  •  34
  •   Darren    8 年前

    下面是我如何验证一个方法是否被调用过一次。

    [Test]
    public void just_once()
    {
        // Arrange (Important to GenerateMock not GenerateStub)
        var a = MockRepository.GenerateMock<ISomeDataSource>();
        a.Expect(x => x.GetSomethingThatTakesALotOfResources()).Return(new Something()).Repeat.Once();
    
        // Act
        // First invocation should call GetSomethingThatTakesALotOfResources
        a.GetMeMyThing();
    
        // Second invocation should return cached result
        a.GetMeMyThing();
    
        // Assert
        a.VerifyAllExpectations();
    }
    
        2
  •  16
  •   Jon Cahill    17 年前

        [Test]
        public void just_once()
        {
            var key = "id_of_something";
    
            var source = MockRepository.GenerateStub<ISomeDataSource>();
    
            // set a positive expectation
            source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
                .Return(new Something())
                .Repeat.Once();
    
            var client = new Client(soure);
            client.GetMeMyThing(key);
            client.GetMeMyThing(key);
    
            source.AssertWasCalled(x => x.GetSomethingThatTakesALotOfResources(key),
                                   x => x.Repeat.Once());
            source.VerifyAllExpectations();
        }
    
        3
  •  5
  •   tvanfosson    17 年前

    你可能对我感兴趣 this bit 来自Rhino Mocks 3.5文档(以下引用)。看起来您需要模拟类,而不是存根类,以使其按您期望的方式工作。

    ...

    模拟是我们可以设置的对象 期望,并将验证 预期的行动确实 使用以传递到下的代码 它,所以它会以某种方式行动, 但这些期望永远不会实现 自动表现得像正常人一样 属性,并且您不能设置

    如果要验证 在测试的代码中,您将使用 怀着适当的期望嘲笑, 并验证这一点。如果你想 传递一个可能需要在 在这个测试中,您将使用存根。

    测试失败。

        4
  •  2
  •   Christopher Bennage    17 年前

    以下是我刚才所做的(按照 Ray Houston

    [Test]
    public void just_once()
    {
        var key = "id_of_something";
    
        var source = MockRepository.GenerateStub<ISomeDataSource>();
    
        // set a positive expectation
        source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
            .Return(new Something())
            .Repeat.Once();
    
        var client = new Client(soure);
    
        client.GetMeMyThing(key);
    
        // set a negative expectation
        source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
            .Return(new Something())
            .Repeat.Never();
    
        client.GetMeMyThing(key);
    }
    
        5
  •  2
  •   Ergwun    15 年前

    您可以在呼叫计数时将呼叫传递给代理:

    ...
    uint callCount = 0;
    source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
        .Return(new Something())
        .WhenCalled((y) => { callCount++; });
    ...
    Assert.AreEqual(1, callCount);
    

    此外,您应该使用模拟而不是存根,并验证对模拟的期望。

        6
  •  0
  •   Balpreet Patil    8 年前

    如果希望确保只调用一次方法,可以创建strict mock。

    var mock = MockRepository.GenerateStrictMock<IMustOnlyBeCalledOnce>();
    mock.Expect(a => a.Process()).Repeat.Once();
    var helloWorld= new HelloWorld(mock);
    
    helloworld.Process()
    
    mock.VerifyAllExpectations();
    
        7
  •  -1
  •   Tim Ottinger    17 年前

    拥有一个名为“精确”的特性将便于对可能进入无限循环的代码编写测试。我希望编写一个测试,这样对方法的第二次调用将引发异常。

    犀牛不会那么做的。带有.Once的部分模拟将拦截第一个调用,其余的将传递给原始方法。这很糟糕,但这是真的。

    您必须创建一个手模拟。派生一个“可测试”类,并赋予它在第一次调用后引发的能力。