为什么使用补丁装饰器而不是显式实例化的 MagicMock?
Why Use A Patch Decorator Instead Of An Explicit Instantiated MagicMock?
所以最近在 Python 我开始使用 unittest 库。但是,我无法理解的一件事(我已经尝试查找了好几个小时……)是 为什么 你会在显式 MagicMock 对象上使用补丁装饰器。
更具体地说,下面是我尝试测试的代码。一些快速笔记:
该代码正在尝试测试一些餐厅的简单菜单 class。
在 setUp
方法中,我通过存储一些实例化的 Food 对象(在本例中由 MagicMock 对象替换)来准备实例化的 Menu 对象。
在 testFindItem
方法中,我试图通过搜索名称从菜单中找到并 return 一个 Food 对象。然后我将找到的对象与假设的 Food 对象(在本例中为 MagicMock 对象)进行比较。
话虽如此,请观察我如何在 setUp
方法中将 self.bread
和 self.cardboard
替换为 MagicMock 对象而不是 Food 对象。代码有效,这很好,但另一种方法是使用覆盖 Food class 的补丁装饰器。
TL;DR: 为什么在这种情况下(即使用补丁)会更好或更糟?或者更确切地说,如前所述,为什么在显式 MagicMock 对象上使用补丁装饰器?
哦,顺便说一句,我找到的最接近的答案是另一个 post,它讨论了 patch 和 mock 之间的区别,但没有讨论 为什么 你会使用一个在另一个之上: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")
这不是补丁的用例。您使用它的原因是当您想要替换在别处定义的对象时。在这里,您显式地实例化了 Menu 并传入了您想要对其调用断言的东西,因此 patch 没有用;但是很多时候 class 被测对象会创建自己的对象,或者从代码的其他部分获取它们,这就是您使用补丁的时候。
所以最近在 Python 我开始使用 unittest 库。但是,我无法理解的一件事(我已经尝试查找了好几个小时……)是 为什么 你会在显式 MagicMock 对象上使用补丁装饰器。
更具体地说,下面是我尝试测试的代码。一些快速笔记:
该代码正在尝试测试一些餐厅的简单菜单 class。
在
setUp
方法中,我通过存储一些实例化的 Food 对象(在本例中由 MagicMock 对象替换)来准备实例化的 Menu 对象。在
testFindItem
方法中,我试图通过搜索名称从菜单中找到并 return 一个 Food 对象。然后我将找到的对象与假设的 Food 对象(在本例中为 MagicMock 对象)进行比较。
话虽如此,请观察我如何在 setUp
方法中将 self.bread
和 self.cardboard
替换为 MagicMock 对象而不是 Food 对象。代码有效,这很好,但另一种方法是使用覆盖 Food class 的补丁装饰器。
TL;DR: 为什么在这种情况下(即使用补丁)会更好或更糟?或者更确切地说,如前所述,为什么在显式 MagicMock 对象上使用补丁装饰器?
哦,顺便说一句,我找到的最接近的答案是另一个 post,它讨论了 patch 和 mock 之间的区别,但没有讨论 为什么 你会使用一个在另一个之上: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")
这不是补丁的用例。您使用它的原因是当您想要替换在别处定义的对象时。在这里,您显式地实例化了 Menu 并传入了您想要对其调用断言的东西,因此 patch 没有用;但是很多时候 class 被测对象会创建自己的对象,或者从代码的其他部分获取它们,这就是您使用补丁的时候。