So lately in Python I started using the unittest library. However, one thing that I cannot understand (and I've tried looking this up for hours and hours...) is why you would use the patch decorator over an explicit MagicMock objects.
To be more specific, below is my code that I am attempting to test. Some quick notes:
The code is attempting to test a simple menu class for some restaurant.
In the
setUp
method, I am preparing the instantiated Menu object by storing some instantiated Food objects (which in this case are replaced by MagicMock objects).In the
testFindItem
method, I am attempting to find and return a Food object from the menu via searching for it's name. Then I compare the found object with the Food object (MagicMock object in this case) it is suppose to be.
Now that being said, observe how in the setUp
method I replaced self.bread
and self.cardboard
by MagicMock objects instead of Food objects. The code works, and that is great but an alternative would be to use a patch decorator that overrides the Food class.
TL;DR: Why would that (i.e. using a patch) be better or worse in this case? Or rather as mentioned before, why use patch decorator over explicit MagicMock objects?
Oh on a side note, the closest answer that I have found is another post which discusses the difference between patch and mock but not why you would use one over the other: Mocking a class: Mock() or patch()?
class MenuTest(unittest.TestCase):
"""
Unit test class for Menu class.
"""
def setUp(self):
"""
Prepares a menu to be tested against using mock objects.
"""
self.bread = MagicMock()
self.cardboard = MagicMock()
self.bread.name = "bread"
self.cardboard.name = "cardboard"
foodItems = [self.cardboard, self.bread]
self.menu = Menu(foodItems)
def testFindItem(self):
"""
Tests whether a specified food item can be found on the menu.
"""
# Items on the menu
self.assertEqual(self.menu.findItem("bread"), self.bread)
self.assertEqual(self.menu.findItem("cardboard"), self.cardboard)
# Items not on the menu
with self.assertRaises(NameError):
self.menu.findItem("salvation")