【问题标题】:How to unit test function that has an external function call using pytest如何使用 pytest 对具有外部函数调用的函数进行单元测试
【发布时间】:2018-05-09 11:19:27
【问题描述】:

我有一个带有内部函数调用 (db_fetch) 的函数 foo(par1),这是一个使用 SQLAlchemy 获取存储值的数据库调用,如下所示:

def foo(par1):
    db_value = db_fetch(par1)
    if db_value > 10:
        return db_value * 5
    else:
        return 1

我目前正在创建一个 db pytest 夹具并在每次运行测试套件时加载测试数据,以便为 db_fetch 函数调用提供数据。如何将测试转换为使用 db_fetch 函数调用的虚拟数据来加速测试运行?

【问题讨论】:

标签: python unit-testing sqlalchemy pytest


【解决方案1】:

您可以:

1-使用依赖注入(改变你的函数定义方式,这样更容易测试)

def foo(par1, fetch_function):
    db_value = fetch_function(par1)
    if db_value > 10:
        return db_value * 5
    else:
        return 1

在普通代码中,这样调用它:

foo(my_par_1, db_fetch)

代替:

foo(my_par1)

在单元测试中,这样称呼它:

foo(my_par_1, lambda par: 42)

因此,在单元测试期间,该值将始终为 42,而不是真正的数据库值。

2- 模拟对 fetch_function 的调用

在你的单元测试中,而不是调用:

foo(my_par1)

你应该打电话:

mock = MagicMock(return_value=42)
with patch('fetch_function', mock):
    foo(my_par1)

如果 fetch_function 是从模块中导入的,您可能必须编写 'my_module.fetch_function' 而不是 'fetch_function'。 请参阅文档:https://docs.python.org/3/library/unittest.mock-examples.html 有几种方法可以进行模拟,并且有几个库可以完成这项工作。

3- 制作一个 pytest 夹具,以便每个单元测试都在特定于测试的内存数据库上运行,该数据库仅包含测试数据。

设置起来比较棘手。

【讨论】:

  • 谢谢,我想我会考虑使用 mock,它看起来比其他选项更具可扩展性。感谢您的帮助。
【解决方案2】:

这被称为存根函数,在 python 中非常简单。 您可以通过以下方式实现此目的:

def stub_foo():
    # some code without the DB stuff...
original_foo = foo
try:
   foo = stub_foo
   # some tests here with the stubbed function
finally:
   foo = original_foo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 2017-05-16
    相关资源
    最近更新 更多