我有一个专门用于启动后台线程的类,从中调用将成为一个管理器。该经理将被嘲笑以进行单元测试。相关的代码片段是:
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
但未发生,而后台线程调用另一个({{1}内) })声明对CacheJanitor
的调用已发生但未被预期。
显然,期望与创建它们的线程具有亲和力。有没有人知道一种方法来指示Rhino Mocks期望在不同的线程上调用(在预期定义时甚至不存在)?
编辑:
忘了提及我们在不久的将来仍然在VS 2005上的约束。 Rhino Mocks版本是3.4 - 我将尝试使用3.5,但改进列表似乎并未表明此区域有任何修复。
目前我可能会为这一系列测试创建我自己的模拟对象,并在其中记录结果,但绝对会欣赏任何允许我使用Rhino Mocks干净地实现此目标的解决方案。
答案 0 :(得分: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);