最近在Python中我开始使用unittest库。但是,我无法理解的一件事(我已经尝试了几个小时......)为什么你会使用补丁装饰器而不是显式的MagicMock对象。
更具体地说,下面是我试图测试的代码。一些快速说明:
代码正在尝试为某家餐馆测试一个简单的菜单类。
在setUp
方法中,我通过存储一些实例化的Food对象(在本例中由MagicMock对象替换)来准备实例化的Menu对象。
在testFindItem
方法中,我试图通过搜索菜单的名称来查找并返回菜单中的Food对象。然后我将找到的对象与Food对象(在这种情况下是MagicMock对象)进行比较,假设它是。
现在说,观察我在setUp
方法中如何用MagicMock对象替换self.bread
和self.cardboard
而不是Food对象。代码工作,这很好,但另一种方法是使用覆盖Food类的补丁装饰器。
TL; DR:在这种情况下,为什么(即使用补丁)会更好还是更差?或者更确切地说,如前所述,为什么要使用补丁装饰器而不是显式的MagicMock对象?
哦,在旁注中,我找到的最接近的答案是另一篇文章讨论补丁和模拟之间的区别,但不是为什么你会使用其中一个: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")
答案 0 :(得分:1)
这不是补丁的用例。您使用它的原因是您想要替换其他地方定义的对象。在这里,你明确地实例化了Menu并传入了你想要调用断言的东西,所以补丁没用;但是很多时候,被测试的类会创建自己的对象,或者从代码的其他部分获取它们,以及当你使用补丁时。