1

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

 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 干净地实现这一目标的解决方案。

4

1 回答 1

1

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

你用的是什么版本的犀牛?您以 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);
于 2008-10-08T13:21:58.767 回答