【问题标题】:NMock2.0 - how to stub a non interface call?NMock2.0 - 如何存根非接口调用?
【发布时间】:2011-01-18 20:33:51
【问题描述】:

我有一个类 API,它具有完整的代码覆盖率,并使用 DI 模拟了完成所有工作的主类函数 (Job.Run) 中的所有逻辑。

我在生产中发现了一个错误,我们没有对其中一个数据输入字段进行验证。

所以,我添加了一个名为 ValidateFoo() 的存根函数...针对该函数编写了一个单元测试以期望 JobFailedException,运行测试 - 它显然失败了,因为该函数是空的。我添加了验证逻辑,现在测试通过了。

太好了,现在我们知道验证有效。问题是 - 我如何编写测试以确保在 Job.Run() 中实际调用了 ValidateFoo()? ValidateFoo() 是 Job 类的私有方法 - 所以它不是接口...

有没有办法用 NMock2.0 做到这一点?我知道 TypeMock 支持非接口类型的假货。但是现在改变模拟库不是一种选择。在这一点上,如果 NMock 不能支持它,我只需将 ValidateFoo() 调用添加到 Run() 方法并手动测试 - 考虑到我的 Job.Run() 方法显然我不想这样做现在100%覆盖。有什么建议吗?非常感谢,不胜感激。

编辑:我想到的另一个选择是为我的 Job.Run 功能创建一个集成测试(向它注入复合对象的真正实现而不是模拟)。我将为该字段提供一个错误的输入值,然后验证作业是否失败。这有效并涵盖了我的测试 - 但它不是真正的单元测试,而是测试一个功能单元的集成测试....嗯..

EDIT2:有什么办法可以做到吗?有人有想法吗?也许 TypeMock - 或者更好的设计?

【问题讨论】:

    标签: tdd mocking typemock nmock


    【解决方案1】:

    The current version of NMock2 可以使用最熟悉的语法来模拟具体类型(我不记得他们添加的确切版本,但我们使用的是 2.1 版本):

    Job job = mockery.NewMock<Job>(MockStyle.Transparent);
    Stub.On(job).Method("ValidateFoo").Will(Return.Value(true));
    

    MockStyle.Transparent 指定您不存根或期望的任何内容都应由底层实现处理 - 因此您可以存根并为正在测试的实例上的方法设置期望。

    但是,您只能对公共方法(和属性)进行存根和设置期望,这些方法也必须是虚拟的或抽象的。因此,为避免依赖集成测试,您有两种选择:

    • Job.ValidateFoo() 设为公开和虚拟。
    • 将验证逻辑提取到新类中,并将实例注入Job

    【讨论】:

      【解决方案2】:

      由于所有私有都由公共方法调用(除非依赖于反射运行时执行),因此这些私有正在由公共方法执行。这些私有方法导致对象的更改不仅仅是执行代码,例如设置类字段或调用其他对象。我会找到一种方法来获得调用私有方法的那些“结果”。 (或者嘲笑那些不应该在私有方法中执行的事情。)

      我看不到正在测试的课程。另一个可能促使您想要访问私有方法的问题是,它是一个具有大量私有功能的超级大类。这些类可能需要分解成更小的类,其中一些私有类可能会变成更简单的公共类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        • 1970-01-01
        • 2012-01-22
        • 2016-08-29
        • 2019-06-27
        • 2019-02-11
        相关资源
        最近更新 更多