Python补丁装饰器影响其他方法
我的理解是,当你在单元测试中使用补丁装饰器时(我用的是nose框架),这个补丁装饰器的作用范围就是这个测试用例的范围。问题在这里:
@patch('a')
@patch('b')
@patch('b')
def test_add_stuff(self, mock_a, mock_b, mock_c):
url = '/path/blah/blah'
assert_true(stuff)
# Now those three patch decorators should be "done"
def test_delete_stuff(self):
url = '/another_path/not_important'
assert_true(something)
在我的第二个测试用例test_delete_stuff中,我在实际代码里加了一个打印语句,目的是为了调试一个抛出的错误。结果发现,在通过网址访问的控制器动作中,有一个函数调用返回了一个MagicMock对象!这个对象是来自之前测试用例的mock_b。
如果我只是把这两个测试用例的顺序反过来,结果也没有变化。如果我把带有补丁装饰器的那个测试注释掉,我的第二个测试用例就能通过了。
补充信息: 在这些实例方法所在的类上没有补丁装饰器。
有什么想法吗?
--更新--
结果发现,我没有在函数调用被查找的地方进行模拟,这解决了问题。不过,这并没有解释为什么补丁的作用范围会超过一个测试用例。
如果控制器只有在发送GET请求时才会被实例化,并且控制器文件中的导入被模拟了,为什么MagicMock对象会在多个单元测试中持续存在呢?
1 个回答
1
我想问题出在路径范围上,因为你在 TestCase
类中修改了方法。你可以在官方的 Python unittest.patch
文档中找到相关信息:
Patch 可以作为一个 TestCase 类的装饰器使用。它的工作原理是给类中的每个测试方法添加装饰。这可以减少当你的测试方法共享一组公共补丁时的重复代码。patch() 通过查找以 patch.TEST_PREFIX 开头的方法名来找到测试。默认情况下,这个前缀是 'test',这与 unittest 查找测试的方法一致。你也可以通过设置 patch.TEST_PREFIX 来指定一个不同的前缀。
所以所有以 test
开头的方法都会被添加上补丁。这是默认的行为。