在编写单元测试时,我应该如何处理函数中的外部依赖?

时间:2015-12-31 23:25:38

标签: testing

以下函数遍历文件系统中目录的名称,如果它们不在那里,则将这些名称作为记录添加到数据库表中。 (请注意,此问题适用于大多数语言)。

get_dirs_in_db

我想为此功能编写单元测试。但是,该函数依赖于外部组件 - 数据库。那我该怎么写这个测试呢?

我认为我应该'嘲笑'数据库。这是否意味着我应该将函数def find_new_dirs(get_dirs_in_db): dirs_listed_in_db = get_dirs_in_db() new_dirs = [] for dir in get_directories_in_our_path(): if dir not in dirs_listed_in_db: new_dirs.append(dir) return new_dirs 作为参数,如此?

def find_new_dirs(db):
    dirs_listed_in_db = db.get_dirs()

    new_dirs = []
    for dir in get_directories_in_our_path():
        if dir not in dirs_listed_in_db:
            new_dirs.append(dir)

    return new_dirs

或者可能是这样?

{{1}}

或者我应该采取不同的方法?

另外,我应该从一开始就以这种方式设计我的整个项目吗?或者,在编写测试时,如果需要,我应该将它们重构为这种设计吗?

2 个答案:

答案 0 :(得分:1)

您所描述的内容称为依赖注入,是的,它是编写可测试代码的常用方法。您概述的第二种方法(您将在数据库中传递)可能更常见。此外,您可以让函数的db参数采用默认值,这样您就只能在测试用例中指定模拟数据库。

是否在开始时以这种方式编写代码或稍后修改代码将是一个意见问题,但如果您坚持测试驱动开发(TDD)方法,那么您将编写无论如何,在你的代码测试之前进行测试。

还有其他方法可以解决这个问题,但是你在这一点上提出了一个广泛的问题。

答案 1 :(得分:1)

我认为这些代码片段是python,我不熟悉,但无论如何这看起来像是从任何有状态对象分离的方法,我不确定这是不是习惯性的python或者只是你的设计。

在OOD中,您需要一个对象,该对象在其状态下保存数据访问对象(类似于您的第二个版本)并模拟该对象以进行测试。您还想模仿get_directories_our_path部分。

至于何时应该完成此设计 - 作为创建第一个代码文件之前的第一步。您应该在整个代码中使用依赖注入。这将有助于测试以及解耦和提高课程的可重用性。