我正在测试Django命令,该命令使用名为redminelib
的外部API。
我的模拟类和修补程序在测试中运行良好,但是当我尝试使用两个不同的Mock实例在同一测试中对命令进行两次修补时,第二个命令调用使用第一个模拟类实例。
my_project/app/management/commands/redmine_command.py
中的Django命令:
from redminelib import Redmine
class Command(BaseCommand):
def handle(self, **options):
key = 'project'
redmine_api_instance = Redmine({'user': 'pass'})
redmine_project = redmine_api_instance.project.get(key)
print(redmine_project)
在my_project/app/tests.py
中:
import unittest
import json
from django.core.management import call_command
from django.test import TestCase
class MockProject:
"""A project mock class"""
def __init__(self, time_entries: list):
self.time_entries = time_entries
class MockRedmine(unittest.mock.MagicMock):
"""Class who will mock the redminelib API"""
# Define directory which contains data files
json_data_dir = os.path.join(settings.BASE_DIR, "app/testdata/")
def __init__(self, json_project_file, *args, **kwargs):
super().__init__(json_project_file, *args, **kwargs)
self.project = self.load(json_project_file)
def load(self, json_file):
json_filepath = os.path.join(MockRedmine.json_data_dir, json_file)
with open(json_filepath, "r") as f:
json_dict = json.load(f)
project_dict = {key: MockProject(values) for key, values in json_dict.items()}
return project_dict
# I test some case like this it works:
class TestCommand(TestCase):
def test_invoice_creation_amount_and_update(self):
with unittest.mock.patch("redminelib.Redmine") as redmine_mock_inst:
mock_redmine = MockRedmine("api_case.json")
redmine_mock_inst.return_value = mock_redmine
call_command("my_command")
现在,我使用两个不同的数据集:api_case.json
和other_api_case.json
:
class TestCommadTwice(TestCase):
def test_invoice_creation_amount_and_update(self):
with unittest.mock.patch("redminelib.Redmine") as redmine_mock_inst1:
mock_redmine1 = MockRedmine("api_case.json")
redmine_mock_inst1.return_value = mock_redmine1
call_command("redmine_command")
with unittest.mock.patch("redminelib.Redmine") as redmine_mock_inst:
mock_redmine = MockRedmine("other_api_case.json")
redmine_mock_inst.return_value = mock_redmine
call_command("redmine_command")
我希望redmine_command输出MockRedmine("api_case.json")
然后是MockRedmine("other_api_case.json")
,但是我有两次MockRedmine("api_case.json")
。
答案 0 :(得分:0)
您需要使用unittest.mock.patch("app.management.commands.redmine_command.Redmine")
。
target应该是“ package.module.ClassName”形式的字符串。的 目标被导入,指定的对象被新的替换 对象,因此目标必须可从您所在的环境中导入 从调用patch()。装饰时导入目标 函数执行,而不是在装饰时执行。
另外,请查看https://docs.python.org/3/library/unittest.mock.html#id5的Where to patch
部分。