将Python模块作为参数传递是一种好习惯

时间:2013-09-17 08:45:06

标签: python unit-testing dependency-injection

我对来自Javaland的python很新。我正在写几个模块,想要独立测试它们。其中一些依赖于其他模块中定义的函数。我想在运行测试代码时找到一种轻量级的注入测试模块的方法,并使用它来代替定义这些测试的真实模块。我已经提出了下面的模式作为实现这一目标的手段。

假设我有somemodule.py定义一个函数:

def aFunction:
    return _calculate_real_value_and_do_a_bunch_of_stuff()

foo.py我有一个依赖于该功能的类:

import somemodule

class Foo:
    def bar(self, somemodule=somemodule):
        return 'bar:' + somemodule.aFunction()

在test_foo.py中:

import test_foo

def aFunction:
    return 'test_value'

class FooTest(unittest.TestCase:
    def test_bar(self):
        self.assertEquals('bar:test_value',somemodule.aFunction(test_foo))

这适用于将模块注入Foo.bar,但这是一个好习惯吗?是否有其他更好的方法可以测试具有依赖关系的模块?

我发现代码非常易读,我在函数的参数中获得了依赖列表的额外好处。我看到的唯一缺点是我对somemodule中的foo.py以及它可能闻到的依赖注入POV有明确的依赖性吗?

1 个答案:

答案 0 :(得分:3)

通常的做法是通过monkeypatching。 Python允许你这样做:

import somemodule
somemodule.aFunction = aFunction

现在从foo的角度来看,somemodule.aFunction是您的测试功能。 mock library有一个patch装饰器,它做了很多相同的事情但包装它,以便在测试结束时恢复原件。