Python';调用#u命令';mock也用于其他测试

Python';调用#u命令';mock也用于其他测试,python,django,unit-testing,Python,Django,Unit Testing,使用Django 1.10和python 3.5.1 我试图模拟“call_command”函数来抛出异常。问题是,它似乎在获得“副作用”功能的那一刻——在其他测试中也会保持这种状态。我做错了什么,或者如何“恢复”该功能的副作用 在本例中,在运行其中一个测试之后,之后运行的所有其他测试都将抛出相同的异常,即使该测试中不应该抛出异常 def test_run_migrations_raise_exception(self): with mock.patch('django.core.m

使用Django 1.10和python 3.5.1

我试图模拟“call_command”函数来抛出异常。问题是,它似乎在获得“副作用”功能的那一刻——在其他测试中也会保持这种状态。我做错了什么,或者如何“恢复”该功能的副作用

在本例中,在运行其中一个测试之后,之后运行的所有其他测试都将抛出相同的异常,即使该测试中不应该抛出异常

 def test_run_migrations_raise_exception(self):

    with mock.patch('django.core.management.call_command', return_value=None, side_effect=Exception('e message')):
        self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)
        call_command('run_data_migrations')
        self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)

 def test_run_migrations_raise_flow_exception(self):

    with mock.patch('django.core.management.call_command', return_value=None, side_effect=FlowException(500, 'fe message', {'a': 1})):
        self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)
        call_command('run_data_migrations')
        self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)

您不应该修补模块本地(即Python的“全局”-实际上是“模块”)命名空间中的函数

当你使用Python时,你会这样做

from module.that import this
成为包含导入语句的模块上的变量。对“module.that.this”的任何更改都将影响指向其他模块的对象,但仅使用
this
仍将冻结到原始对象

也许您的代码与您向我们展示的代码不完全一样,或者“mock.pacth”可能会发现模块local
call\u命令
在生成补丁时指向另一个模块中的
django.core.management.call\u命令
,但在反转补丁时却没有。事实上,您的模块本地名称
call\u命令
正在更改

您只需更改代码,不将模块变量直接绑定到要更改的函数,即可解决此问题:

来自django.core导入管理 def测试\运行\迁移\引发\异常(自身):


我希望你能理解并解决这个问题。这就是说,
mock
的这种使用毫无意义:使用mock的想法是,应用补丁的代码块中调用的代码间接使用的一些可调用代码没有原始效果,因此intermatite代码可以运行并测试。您直接调用模拟对象-因此它将没有原始代码-调用
call\u命令('run\u data\u migrations')
在您的代码库上根本不运行任何代码,因此,没有任何代码需要测试。它只调用模拟实例,不会更改任何可以通过
检查迁移\u调用的

检测到的对象的状态。您确定,您的模拟会生效吗?是否该异常是抛出的实际异常(而不是您在副作用中指定的异常?)能否显示名为
check\u migrations>的代码?事实上,这并不是全部代码,但导入分离(导入管理)起了作用。Thanks@user2880391评论是对的,进口的分离为我解决了问题。
with mock.patch('django.core.management.call_command', return_value=None, side_effect=Exception('e message')):
    self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)
    management.call_command('run_data_migrations')
    self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)