3

首先是问题的原因 - 官方 pymox 文档: https ://code.google.com/p/pymox/wiki/MoxDocumentation

MockAnything部分中有一条声明告诉“除非绝对必须,否则不要使用它!” . 我很有趣为什么会这样?它有一些限制吗?我个人觉得它非常有用。

我有以下情况:我在我的班级中有一个对模块的引用,该模块有一堆我的班级使用的模块级函数。

import db

class A(object):
    def __init__(self):
        # To make possible dependency injection.
        self.db = db
    ...

class Test_A(object):
    def test(self):
        a = A()
        # Perform an injection.
        a.db = mox.CreateMockAnything()
        # Setting an expectation to any function
        a.db.some_func().AndReturn(5)
        ...

由于这是一个模块,我无法使用CreateMock()模拟它,因为这不是一种类型。因此,我使用了非常适合这种情况的CreateMockAnything() 。我知道我可以使用以下方法存根模块功能:

self.mox.StubOutWithMock(module_to_mock, 'FunctionToMock') 
module_to_mock.FunctionToMock().AndReturn(foo)

但我不喜欢这种方式,因为这里我每次都需要做两个动作。在类中引用模块并使用CreateMockAnything模拟它更简单、更漂亮。

如果我错误打印了某些函数名称,那么期望就会失败(因为正在测试的代码正在调用正确的代码),所以这不是重点……

对于StubOutWithMock:如果我在测试方法中没有注意到一些额外的 db 函数调用,并且不会存根它StubOutWithMock,它将调用真实代码并在 db 中留下一些垃圾。所以还有一点来保护我的解决方案 - 使用CreateMockAnything而不是存根特定方法可以让我完全切断我的数据库依赖关系,而且我还将看到 MockAnything 模拟引发的意外方法调用异常。

那么避免使用CreateMockAnything()的原因是什么?

谢谢,

4

1 回答 1

0

这样做的主要原因是,在可能的情况下,仅使用具有良好定义接口的对象通常是一种良好的编程习惯。

从我在您的案例中可以看到,这是一个完全可以接受的用例。

于 2015-07-17T12:14:47.293 回答