Python unittest: to mock.patch() or just replace method with Mock?
在Python中编写单元测试时模拟类或方法时,为什么需要使用@patch装饰器? 我只是可以用Mock对象替换方法而不需要任何补丁注释。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class TestFoobar(unittest.TestCase): def setUp(self): self.foobar = FooBar() # 1) With patch decorator: @patch.object(FooBar,"_get_bar") @patch.object(FooBar,"_get_foo") def test_get_foobar_with_patch(self, mock_get_foo, mock_get_bar): mock_get_bar.return_value ="bar1" mock_get_foo.return_value ="foo1" actual = self.foobar.get_foobar() self.assertEqual("foo1bar1", actual) # 2) Just replacing the real methods with Mock with proper return_value: def test_get_foobar_with_replacement(self): self.foobar._get_foo = Mock(return_value="foo2") self.foobar._get_bar = Mock(return_value="bar2") actual = self.foobar.get_foobar() self.assertEqual("foo2bar2", actual) |
有人可以制作一个例子,其中补丁装饰器是好的,替换是坏的吗?
我们总是在我们的团队中使用补丁装饰器,但在阅读了这篇帖子的评论之后,我认为可能我们可以编写更好看的代码而无需补丁装饰器。
我知道修补是暂时的,所以也许在某些情况下,不使用补丁修饰器并用mock替换方法是危险的? 可能是在一个测试方法中替换对象会影响下一个测试方法的结果吗?
我试图证明这一点,但是空了:两个测试都传递到下一个代码中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def test_get_foobar_with_replacement(self): self.foobar._get_foo = Mock(return_value="foo2") self.foobar._get_bar = Mock(return_value="bar2") actual = self.foobar.get_foobar() self.assertIsInstance(self.foobar._get_bar, Mock) self.assertIsInstance(self.foobar._get_foo, Mock) self.assertEqual("foo2bar2", actual) def test_get_foobar_with_real_methods(self): actual = self.foobar.get_foobar() self.assertNotIsInstance(self.foobar._get_bar, Mock) self.assertNotIsInstance(self.foobar._get_foo, Mock) self.assertIsInstance(self.foobar._get_bar, types.MethodType) self.assertIsInstance(self.foobar._get_foo, types.MethodType) self.assertEqual("foobar", actual) |
完整源代码(Python 3.3):dropbox.com/s/t8bewsdaalzrgke/test_foobar.py?dl=0
在测试方法返回后,
在您的两个示例中,您实际上修补了两个不同的东西。 您对
如果每次都从头开始创建对象,则恢复原始对象并不重要。 (您没有显示它,但我假设