如何使用pytest对具有外部函数调用的单元测试函数进行单元测试

时间:2018-05-09 11:19:28

标签: python unit-testing sqlalchemy pytest

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

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

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

2 个答案:

答案 0 :(得分: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 fixture,以便每个单元测试都在一个特定于测试的内存数据库上运行,该数据库只包含测试数据。

设置起来比较棘手。

答案 1 :(得分:0)

这称为存根函数,在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