python - 将 Python 模块作为参数传递是一个好习惯吗

标签 python unit-testing dependency-injection

我对来自 Javaland 的 python 还很陌生。我正在编写一些模块并想独立测试它们。其中一些依赖于其他模块中定义的函数。我想找到一种在运行测试代码时注入(inject)测试模块的轻量级方法,并使用它而不是定义这些测试的真实模块。我想出了下面的模式作为实现这一目标的一种手段。

假设我有 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))

这适用于将模块注入(inject) Foo.bar,但这是好的做法吗?是否还有其他更好的方法来测试具有依赖项的模块?

我发现代码非常可读,并且函数参数中的依赖项列表带来了额外的好处。我看到的唯一缺点是我对 foo.py 中的 somemodule 具有显式依赖,并且从依赖注入(inject) POV 中它可能会闻到什么味道?

最佳答案

通常的方法是通过猴子补丁。 Python 可以让你做到这一点:

import somemodule
somemodule.aFunction = aFunction

现在从 foo 的角度来看,somemodule.aFunction 是您的测试函数。 mock library有一个 patch 装饰器,它执行几乎相同的操作,但将其包装起来,以便在测试结束时恢复原始内容。

关于python - 将 Python 模块作为参数传递是一个好习惯吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18845198/

相关文章:

python - 登录后无法打开新窗口

python - 在 paramiko python 中的 sftp 期间更改了文件权限

python - Pyspark 架构中 StructType 的 VectorType

unit-testing - 在 VS 中为 typescript 运行单元测试

c# - 不可变类和统一应用程序 block

python - doc2vec - python 中 doc2vec 训练和 infer_vector() 的输入格式

java - 您可以为 CLI 应用程序运行 JUnit 测试吗?

c# - Xamarin NUnitLite 测试方法 : How to do shared tests that run in every platform?

java - Dagger 2 与注入(inject)器类

java - Spring @Autowire 许多 bean