【问题标题】:RhinoMocks and HeisenbugsRhinoMocks 和 Heisenbugs
【发布时间】:2010-03-11 13:04:14
【问题描述】:

我最近一直在使用 RhinoMocks,但一直遇到问题。如果我在模拟处于记录模式时闯入调试器并单步执行代码,我最终会收到如下异常:

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

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

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

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

谢谢,

~贾斯汀

【问题讨论】:

    标签: debugging rhino-mocks moq typemock


    【解决方案1】:

    我记得很多年前 NMock 也遇到过类似的问题。基本上,这个问题的发生正是因为调试器使用ToString 方法调用和显示属性(除非您使用 DebuggerDisplayAttribute 或类似方法)。

    如果您使用 strict mocks,这可能会特别成问题,因为它们只允许您调用成员指定的次数,而调试器会干扰这一点。使用 loose mocks 可以解决这个(以及许多其他)问题。

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

    Moq (几乎)完全使用 lamda 语法,我从来没有遇到过这样的问题 - 但话说回来,这些天我没有进行太多调试,因为单元测试已成为调试的替代品。

    另一种补救方法是简单地隐藏 AutosLocals 调试器窗口。

    【讨论】:

    • 感谢您的信息。我还没有看到 lambda 语法。你有一个好的起点链接吗?
    • 通常也称为AAA语法:ayende.com/Wiki/Rhino+Mocks+3.5.ashx
    • 感谢您的链接。关于您的潜在解决方案,我仅隐藏 Autos 和 Locals 并没有成功。我认为即使它们被隐藏,调试器仍在执行 ToString()。
    • 接受为答案。它没有直接解决 heisenbug 问题,但它是一种替代方案。
    【解决方案2】:

    正如 Mark 所建议的,如果您停止使用记录重放验证方法并开始使用推荐的 AAA 方法(排列、动作、断言)的存根,这个问题应该会消失。

    我已尝试在 blog post 中解释其中的区别以及如何使用 Rhino Mocks。

    【讨论】:

    • 对我来说,AAA 与记录重放验证并不矛盾;相反,它只是描述了测试的整体组织,任何测试,无论是否使用模拟 API。 “Record-replay-verify”简单地描述了使用面向行为的模拟 API 的测试组织,其中 expectations 可以被记录,然后重放,最后验证。
    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多