首页 > 解决方案 > 我应该注入像 os 或 json 这样的 python 内置库(通过工厂类)以使我的代码可单元测试吗?

问题描述

我正在重构我的整个项目,通过类的构造函数注入依赖项,使其可单元测试。这消除了以独立方式实例化对象的实例(这不是单元可测试的,因为我不再直接控制这些对象)。如果我应该注入像 os 或 json 这样的 python 内置模块,我很困惑。

我创建了一个工厂,它具有返回类或对象的静态方法。这使得依赖注入成为可能。

最初 :

import json

def do_something(self):
    object_a = UserClassA()
    some_value = json.dumps({})

目前 :

def do_something(self, factory_object):
    object_a = factory_object.get_user_class_a()
    some_value = factory_object.get_json().dumps({})

后一种实现使其可单元测试。自定义类 A 和内置模块 json 都已处理。但是,以这种方式注入 json 是使代码可单元测试的正确方法吗?还是打补丁更好?

标签: python-2.7unit-testingrefactoring

解决方案


TL; DR:你在这里过分了!!!

虽然在某些用例中使用依赖注入是有意义的,但至少可以说您的方法有点极端。您是否计划为内置类型和函数提供 DI?-)

Python 是动态的——非常动态的——所以很容易用你想要的任何东西来修改模块的顶级名称,手动或使用mock.

wrt/你的例子,保持原来的代码是:

import json

class UserClassA():
   # ....

class Foo(object):
    def do_something(self):
        object_a = UserClassA()
        some_value = json.dumps({})

并且在您的测试中,monkeypatch 或 mockyourmodule.json和/或yourmodule.UserClassA- 并保留 DI 以供正常使用时使用(IOW,不要添加 DI 仅用于联合,除非您有特殊情况,monkeypatch/mock 解决方案真的是真的真的很不方便,但实际上这种情况很少见)。

编写代码以便更容易进行单元测试(通过支持纯函数,保持函数和类很好地专注于单一责任等)是一个很好的举措 - 正确完成通常会导致代码也更易于阅读和维护。但是单元测试不是目标 - 目标是一个程序(按重要性顺序)1/正确(做它应该做的事情),2/健壮(正确处理极端情况和意外情况而不会损坏您的宝贵数据或产生错误结果),并且 3/ 可维护。

拥有良好的单元测试覆盖率有助于实现这三个目标,但前提是它不会将您的代码库变成过度设计的、难以理解的混乱,并带有无用的间接级别,实际上除了取悦“敏捷”狂热者之外没有其他意义。如有疑问,请检查此

哦,是的:单元测试不是免费的——你必须编写它们,但更重要的是,你必须在代码更改时维护它们。所以也不要落入“100% 单元测试覆盖率”的陷阱,你最想测试(我的意思是自动化测试)关键的东西。


推荐阅读