我的django应用程序中有几个TestCase类。在其中一些中,我模拟了一个函数,它通过使用@ mock.patch修改类来调用外部资源,这非常有用。我的测试套件中的一个TestCase,我们称之为B(),依赖于外部资源,因此我不希望它被模拟,我不添加装饰器。它看起来像这样:
@mock.patch("myapp.external_resource_function", new=mock.MagicMock)
class A(TestCase):
# tests here
class B(TestBase):
# tests here which depend on external_resource_function
当我独立测试B时,事情按预期工作。但是,当我同时运行两个测试时,A首先运行,但该功能仍然在B中模拟出来。我怎么能取消该调用?我已经尝试重新加载模块,但它没有帮助。
答案 0 :(得分:5)
补丁有start and stop methods。根据我从您提供的代码中看到的内容,我将删除装饰器并使用类中链接中的setUp和tearDown方法。
class A(TestCase):
def setUp(self):
self.patcher1 = patch('myapp.external_resource_function', new=mock.MagicMock)
self.MockClass1 = self.patcher1.start()
def tearDown(self):
self.patcher1.stop()
def test_something(self):
...
>>> A('test_something').run()
答案 1 :(得分:1)
很棒的答案。关于Ethereal的问题,补丁对象的使用非常灵活。
这是进行需要不同补丁的测试的一种方法。您仍然可以使用setUp和tearDown,但不能使用patch.start / stop位。
你开始()每个测试中的补丁,你使用finally子句来确保它们被停止()。
补丁也支持Context Manager的东西,这是另一个选项,这里没有显示。
class A(TestCase):
patcher1 = patch('myapp.external_resource_function', new=mock.MagicMock)
patcher2 = patch('myapp.something_else', new=mock.MagicMock)
def test_something(self):
li_patcher = [self.patcher1]
for patcher in li_patcher:
patcher.start()
try:
pass
finally:
for patcher in li_patcher:
patcher.stop()
def test_something_else(self):
li_patcher = [self.patcher1, self.patcher2]
for patcher in li_patcher:
patcher.start()
try:
pass
finally:
for patcher in li_patcher:
patcher.stop()