【问题标题】:Should I inject python built-in libraries like os or json (via factory class) to make my code unit testable?我应该注入像 os 或 json 这样的 python 内置库(通过工厂类)以使我的代码可单元测试吗?
【发布时间】:2019-09-04 20:48:29
【问题描述】:

我正在重构我的整个项目,通过类的构造函数注入依赖项,使其可单元测试。这消除了以独立方式实例化对象的实例(这不是单元可测试的,因为我不再直接控制这些对象)。如果我应该注入像 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.7 unit-testing refactoring


    【解决方案1】:

    TL;DR :你在这方面做得太过分了!!!

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

    Python 是动态的 - 非常动态的 - 所以很容易用你想要的任何东西来猴子补丁模块的顶级名称,手动或 using mock

    wrt/ 你的例子,保持原代码不变:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-11-06
      • 1970-01-01
      • 2012-08-07
      • 2010-11-14
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多