在TestCase.setUp()中进行模拟

gue*_*tli 2 python unit-testing mocking

我想模仿a的所有测试方法TestCase.

我的第一次尝试使用TestCase.setUp()不起作用,因为setUp()在测试方法执行之前完成.

我无法用这个内部模拟真正的测试方法setUp():

with mock.patch(...):
    do_something()
Run Code Online (Sandbox Code Playgroud)

我想我错过了一些东西.

如何使用mock.patch()测试用例的所有方法?

Mar*_*ers 7

with mock.patch()是一个上下文管理器,当上下文结束时,补丁未被应用,并且上下文在代码块的末尾结束.

这意味着在setUp()结束时不再应用补丁.

你的选择是要么使用@mock.patch()一个类装饰或使用startstop方法上patchers.

使用@mock.patch()作为类装饰器与将其作为装饰器应用于每个测试方法具有相同的效果:

@mock.patch('module.ClassName')
class TestFoo(unittest.TestCase):
    def setUp(self):
        # ...

    def test_one(self, class_mock):
        # ...

    def test_two(self, class_mock):
        # ...
Run Code Online (Sandbox Code Playgroud)

这里既有test_onetest_two在模拟对象的传递,因为@mock.patch()类装饰发现所有的测试方法和装饰他们.

使用start和stop方法可以在setUptearDown方法中应用和取消应用补丁:

class TestFoo(unittest.TestCase):
    def setUp(self):
        self.patch1 = mock.patch(...)
        self.patch1.start()

    def tearDown(self):
        self.patch1.stop()
Run Code Online (Sandbox Code Playgroud)

patch1是从设置开始,并在测试被拆除时再次停止.这就像上下文管理器一样,但是它会挂钩到测试边界.

tearDown您也可以将以下内容注册patch.stop()为清理函数,而不是使用TestCase.addCleanup();

class TestFoo(unittest.TestCase):
    def setUp(self):
        patch1 = mock.patch(...)
        patch1.start()
        self.addCleanup(patch1.stop)
Run Code Online (Sandbox Code Playgroud)