如何为多个测试模拟全局变量评估?

时间:2019-04-04 14:09:00

标签: python unit-testing mocking python-unittest

我需要在python脚本中模拟全局变量。

使用相当昂贵的方法初始化此变量,该方法在目标环境之外运行时也会抛出该异常。

我发现了一次模拟该变量的方法,但是随后的模拟似乎并没有改变初始变量(提供示例)。

正在测试的脚本: 服务/实体/列表/src/handler.py

from util.table import get_table

table = get_table('TABLE')

def query_db(event):
    query_args = create_query_params(event)
    query_res = table.query(**query_args)
    return query_res

我需要模拟的功能: util / table.py

def get_table(table_name):
    return get_db().table(table_name)

我尝试过的事情:

  1. 模拟使用的地方
class TestListEntities(TestCase):
    def setUp(self):
        self.event = MagicMock(name='event mock')
        self.table = MagicMock(name='table mock')
        self.query = MagicMock(name='query mock')
        self.query_result = {'items': []}
        self.table.query.return_value = self.query_result

    def test_empty(self):
        with patch('service.entity.list.src.handler.get_table', return_value=self.table):
            from service.entity.list.src.handler import query_db
            response = query_db(self.event)

            self.assertTrue(self.table.query.called)

这会在测试甚至开始之前调用真实方法。

  1. 模拟实施的地方
    def test_empty(self):
        with patch('util.table.get_table', return_value=self.table):
            from service.entity.list.src.handler import query_db
            response = query_db(self.event)
            self.assertTrue(self.table.query.called)

可以正常工作,但是其他测试用例中的补丁程序不会更改此补丁程序,并且测试失败。

TL; DR 我需要修补多个测试用例的全局变量初始化,但只能成功执行一次。

2 个答案:

答案 0 :(得分:0)

尝试这个:

import lang_module
from mock import patch
@patch('languages.list', ['EN', 'ES', 'DE'])
class TestLanguages():

    def test_length(self):
        assert 3 == lang_module.get_length()

    def test_contains_lang(self):
       assert lang_module.contains_lang('EN')

答案 1 :(得分:0)

My recommendation is, to replace the accesses to global variables by getter methods.

For one thing it can help to solve your current problem: You can make the getter method initialize the variable on the first call. Therefore, if you mock it before the first call, the true initialization function does not get called.

Getter functions also offer more freedom than direct variable accesses in other cases, namely when you want to simulate that the value of the global variable changes between two accesses. Generally, in contrast to a direct variable access, the call of a function is always a possible point for you to take control.

相关问题