为什么使用修补程序装饰器而不是显式实例化MagicMock?

时间:2016-02-21 14:20:23

标签: python unit-testing mocking

最近在Python中我开始使用unittest库。但是,我无法理解的一件事(我已经尝试了几个小时......)为什么你会使用补丁装饰器而不是显式的MagicMock对象。

更具体地说,下面是我试图测试的代码。一些快速说明:

  • 代码正在尝试为某家餐馆测试一个简单的菜单类。

  • setUp方法中,我通过存储一些实例化的Food对象(在本例中由MagicMock对象替换)来准备实例化的Menu对象。

  • testFindItem方法中,我试图通过搜索菜单的名称来查找并返回菜单中的Food对象。然后我将找到的对象与Food对象(在这种情况下是MagicMock对象)进行比较,假设它是。

现在说,观察我在setUp方法中如何用MagicMock对象替换self.breadself.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")

1 个答案:

答案 0 :(得分:1)

这不是补丁的用例。您使用它的原因是您想要替换其他地方定义的对象。在这里,你明确地实例化了Menu并传入了你想要调用断言的东西,所以补丁没用;但是很多时候,被测试的类会创建自己的对象,或者从代码的其他部分获取它们,以及当你使用补丁时。