When confusing classes or methods when writing unittests in Python, why should I use @patch decorator? I can simply replace the method with a Mock object without annotating the patches.
Examples:
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)
Can someone give an example where fixing the patch is good and replacing it is bad?
We always used a patch decorator with our team, but after reading this comment for publication, I had the idea that, perhaps, we could write more beautiful code without the need to fix the patches.
I understand that the fix is temporary, so it may be dangerous in some cases not to use patch fix and replace methods instead? Maybe replacing objects in one test method can affect the result of the next test method?
I tried to prove it, but came up empty: both tests pass in the following code:
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)
Full source code (Python 3.3): dropbox.com/s/t8bewsdaalzrgke/test_foobar.py?dl=0
python decorator unit-testing mocking
kristjanroosild
source share