python - 如何在 Python 中进行基本的依赖注入(inject)(用于模拟/测试目的)

标签 python unit-testing dependency-injection mocking

Python 对我来说是一门相对较新的语言。单元测试和依赖注入(inject)是我已经做了一段时间的事情,所以我从 C# 的角度来熟悉它。

最近写了一段Python代码:

import requests  # my dependency: http://docs.python-requests.org/en/latest/

class someClass:
    def __init__(self):
        pass

    def __do(self, url, datagram):
        return requests.post(self, url, datagram)

然后我意识到我刚刚创建了一个硬编码的依赖项。呸。

我曾考虑更改我的代码以执行“构造函数”依赖注入(inject):

def __init__(self,requestLib=requests):
    self.__request = requestLib

def __do(self, url, datagram):
    return self.__request.post(self, url, datagram)

这现在允许我为了单元测试注入(inject)一个假的/模拟的依赖,但不确定这是否被认为是 Python-ic。所以我呼吁 Python 社区提供指导。

有哪些 Python 风格的基本 DI 方法示例(主要是为了编写利用 Mocks/Fakes 的单元测试)?

附录 对于任何对模拟答案感到好奇的人,我决定在这里问一个单独的问题:How does @mock.patch know which parameter to use for each mock object?

最佳答案

不要那样做。只需像往常一样导入请求并像往常一样使用它们。将库作为参数传递给你的构造函数是一件有趣的事情,但不是很 pythonic 并且对于你的目的来说是不必要的。要在单元测试中模拟事物,请使用模拟库。在 python 3 中,它内置于标准库中

https://docs.python.org/3.4/library/unittest.mock.html

而在 python 2 中你需要单独安装它

https://pypi.python.org/pypi/mock

你的测试代码看起来像这样(使用 python 3 版本)

from unittest import TestCase
from unittest.mock import patch

class MyTest(TestCase):
    @patch("mymodule.requests.post")
    def test_my_code(self, mock_post):
        # ... do my thing here...

关于python - 如何在 Python 中进行基本的依赖注入(inject)(用于模拟/测试目的),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33349025/

相关文章:

python - 测试 Flask 应用程序时保留多个功能的更改

c# - Ninject 中的 .NET Core DI 作用域生命周期

python - 为 ASCII 数据添加名称和分配数据类型

python - torch.empty 如何计算这些值?

c# - Moq 定义严格的模拟

c# - Rhino Mocks - 通过多次调用模拟其返回值发生变化(即使传递相同参数)的方法

java - 更改 Guice 参数配置

asp.net-mvc - Ninject 获取实例时出现问题

python - 单元测试和多个模块的 ImportError

Android Espresso 测试套件