RhinoMocks和Heisenbugs

时间:2010-03-11 13:04:15

标签: debugging rhino-mocks moq typemock

我最近一直在使用RhinoMocks,但我一直遇到问题。如果我在模拟处于记录模式时闯入调试器并跳过代码,我最终会得到一个例外:

System.InvalidOperationException: Previous method 'SuchAndSuch.ToString();'  
requires a return value or an exception to throw.

但是如果我执行相同的代码而不进入调试器,它将成功执行并创建模拟。

我很确定这样做的原因是调试器调用对象上的ToString()以在Locals和其他Watch窗口中显示它们。但是由于模拟处于记录模式,RhinoMocks认为对ToString()的调用是一种期望的设置,然而这种期望并不完全正确。显然,这只发生在具体类的部分模拟中。针对接口的模拟不会出现此行为。

是否有其他人遇到此问题?有什么简单的补救措施吗?其他框架如moq或TypeMock有这个问题吗?

谢谢,

~Justin

2 个答案:

答案 0 :(得分:3)

我记得多年前和NMock有过类似的问题。基本上,出现此问题的原因完全是因为调试器使用ToString方法调用并显示属性(除非您使用DebuggerDisplayAttribute或类似方法)。

如果您使用 strict mocks ,这可能会特别成问题,因为它们只允许您调用指定次数的成员,并且调试器会干扰此操作。使用宽松的模拟解决了这个(和许多其他)问题。

您可能还想远离Rhino Mocks的录制/播放机制,并开始使用更新更好的 lambda语法

Moq使用lamda语法(差不多),并且我从来没有遇到过这样的问题 - 但是再一次,我现在调试不多,因为单元测试已经成为调试的替代品。

另一种补救措施就是隐藏 Autos Locals 调试器窗口。

答案 1 :(得分:-1)

正如Mark建议的那样,如果您停止使用record-replay-verify方法并开始使用建议的AAA方法(安排,执行,断言)的存根,则此问题应该消失。

我试图解释这个差异,以及如何在这个blog post中使用Rhino Mocks。