【问题标题】:How to set expectations for calls which will be made on another thread in Rhino Mocks如何为将在 Rhino Mocks 中的另一个线程上进行的调用设置期望
【发布时间】:2008-10-08 13:09:22
【问题描述】:

我有一个类,旨在启动一个后台线程,从中调用一个管理器。出于单元测试的目的,该经理将被嘲笑。相关的代码片段是:

 MockRepository mocks = new MockRepository();
ICacheManager manager = mocks.CreateMock<ICacheManager>();

Expect.On(manager).Call(manager.CacheSize).Return(100);
mocks.ReplayAll();

CacheJanitor janitor = new CacheJanitor(manager);

// get janitor to do its stuff
// ...

mocks.VerifyAll();

问题是,在验证后,我们抛出了两个异常 - 一个在测试线程上表明预期调用 CacheSize 但没有发生,另一个在后台线程(在 CacheJanitor 内)表明发生了对 CacheSize 的调用,但不是预期的。

显然,期望与创建它们的线程有密切关系。有谁知道一种方法来指示 Rhino Mocks 期望在不同的线程上进行调用(在定义期望时甚至不存在)?

编辑:

忘记提及我们在不久的将来仍然使用 VS 2005 的限制。 Rhino Mocks 版本是 3.4 - 我将尝试使用 3.5,但改进列表似乎并未表明该领域有任何修复。

目前我可能会为这一系列测试创建自己的模拟对象并在其中记录结果,但肯定会感谢任何允许我使用 Rhino Mocks 干净地实现这一目标的解决方案。

【问题讨论】:

    标签: c# nunit rhino-mocks


    【解决方案1】:

    哇。太疯狂了。我已经使用 MoQ 毫无问题地做这种事情。

    您使用的是什么版本的 Rhino?您以 3.5 之前的方式使用它;也许这不会是 3.5 版的问题?

    另一种选择是避免验证对模拟的期望。 (对不起,我不熟悉 Rhino 的语法,但它可能是可能的)。使用回调在测试函数中设置局部变量并验证该变量。

    在 MoQ 中,我会这样做:

    // Arrange
    var called = false;
    var mock = new Mock<SomeObject>();            
    
    mock.Expect(x => SomeFunction()).Callback(() => called = true);            
    
    var target = new MultithreadedTarget(mock.Object);            
    
    // Act
    target.DoSomethingThatCallsSomeFunctionOnAnotherThreadLol();            
    
    // this part is a bit ugly
    // spinlock for a bit to give the other thread a chance
    var timeout = 0;
    while(!called && timeout++ < 1000)
      Thread.Sleep(1);
    
    // Assert
    Assert.IsTrue(called);
    

    【讨论】:

    • 不幸的是,这只有一半适用于 RM。我仍然在后台线程上遇到期望违规,因为我无法告诉 RM 期望或忽略它。这个异常显然是在访问 mocked 属性时抛出的,而不是在调用 VerifyAll 时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    相关资源
    最近更新 更多