Mox(pymox)框架的CreateMockAnything()的优点和缺点

时间:2013-09-06 16:15:51

标签: python unit-testing mocking pymox

首先问题的原因 - 官方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模拟引发的意外方法调用异常。 / p>

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

谢谢,

1 个答案:

答案 0 :(得分:0)

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

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