【问题标题】:Invalid call, the last call has been used or no call has been made通话无效,上次通话已使用或未通话
【发布时间】:2009-08-19 16:31:21
【问题描述】:

当我尝试将模拟设置为具有 PropertyBehavior() 时出现此错误:

System.InvalidOperationException: System.InvalidOperationException: 无效调用,已使用最后一次调用或未进行调用(确保您正在调用虚拟(C#)/可覆盖(VB)方法)..

我正在尝试仅使用 Rhino Mocks 3.5(排列、动作、断言)

这是我的代码:

    private IAddAddressForm form;

    private AddAddressMediator mediator;

    [TestInitialize()]
    public void MyTestInitialize()
    {
        form = MockRepository.GenerateMock<IAddAddressForm>();
        mediator = new AddAddressMediator(form);


        // Make the properties work like a normal property
        Expect.Call(form.OKButtonEnabled).PropertyBehavior();

        //I tried this too.  I still get the exception
        //SetupResult.For(form.OKButtonEnabled).PropertyBehavior();
    }


    [TestMethod]
    public void TestOKButtonEnabled()
    {

        form.OKButtonEnabled = true;
        Assert.IsTrue(form.OKButtonEnabled);
    }

我知道我可以使用存根(对于上面的代码我应该),但我正在尝试学习 Rhino Mocks。

最终,我希望能够确保访问多个属性的值。 (任何关于如何检查 form.FirstName 是否被访问(即调用 getter)的提示也将不胜感激。)

如果需要,这里是IAddressForm的代码:

namespace AddressBook
{
    public interface IAddAddressForm
    {
        string FirstName { get; set; }
        string LastName { get; set; }
        string Address1 { get; set; }
        string State { get; set; }
        string Address2 { get; set; }
        string ZipCode { get; set; }
        string City { get; set; }
        bool OKButtonEnabled { get; set; }
    }
}

无论如何,我认为 virtual 不会成为问题,因为我正在传递一个接口,但我显然错过了一些东西。

【问题讨论】:

    标签: c# visual-studio visual-studio-2008 rhino-mocks rhino-mocks-3.5


    【解决方案1】:

    以前从未使用过PropertyBehavior,但这是您要查找的语法吗?

    form.Stub(x=>x.OKButtonEnabled).PropertyBehavior()
    

    Rhino Mocks 现在完全通过扩展方法工作。我每次都打的唯一静态电话是MockRepository.GenerateStub

    【讨论】:

    • 扩展方法静态的。
    • 是的,扩展方法是静态的。澄清一下:我们鼓励您在使用 Rhino Mocks 时使用扩展方法,而不是传统的静态调用。
    【解决方案2】:

    您提到使用存根而不是模拟,但在您更改它之前,我会注意到奇怪的是,我在使用 GenerateStub 时收到 Invalid Call 异常,但在使用 GenerateMock 时没有。

    View = MockRepository.GenerateStub<IAddressView>();
    View.Stub(v => v.Message).PropertyBehavior();
    

    这会引发 Invalid call 异常,是的,IAddressView.Message 确实有一个 getter 和 setter。

    【讨论】:

    • 我从 Ayende 的最新版本 3.6 消息中发现这是因为存根默认执行属性行为。
    【解决方案3】:

    当我尝试对非虚拟方法设置期望时收到此错误。

    mockedObject.Expect(a => a.NonVirtualMethod()).Returns(null);
    

    当我将 NonVirtualMethod 设为虚拟时,错误消失了。

    【讨论】:

      【解决方案4】:

      我认为您必须在设置所有期望之后并开始使用此模拟之前执行 MockRepository.ReplyAll()。所以我对你的猜测是,你必须在 mediator = new AddAddressMediator(form); 之前移动 Expect.Call 行,然后再粘贴回复:

      [TestInitialize()]
      public void MyTestInitialize()
      {
          form = MockRepository.GenerateMock<IAddAddressForm>();
          // Make the properties work like a normal property
          Expect.Call(form.OKButtonEnabled).PropertyBehavior();
      
          //I tried this too.  I still get the exception
          //SetupResult.For(form.OKButtonEnabled).PropertyBehavior();
      
          MockRepository.ReplyAll();
          mediator = new AddAddressMediator(form);
      
      
      
      }
      

      【讨论】:

      • 在 Expect.Call 方法上抛出异常(甚至在它到达 MockRepository.ReplayAll() 方法之前。)
      【解决方案5】:

      当我尝试在 C# 中调用对象的 internal 属性(仅限 getter)时遇到了这个问题。在这种情况下,添加 .PropertyBehavior() 并没有帮助。

      我的解决方案是从属性中提取逻辑并放入一个内部方法中,然后我将依赖项注入到该方法中(作为参数)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-01
        • 1970-01-01
        • 2012-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多