嘲笑一个类:赶上22
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嘲笑一个类:赶上22相关的知识,希望对你有一定的参考价值。
简要总结
MyClass.my_method
打电话给instance = SomeLibrary()
我想创建一个模拟器,所以instance
是一个我可以控制的模拟对象。本着孤立测试的精神,我实际上并不想打电话给SomeLibrary
。
什么参数传递给@mock.patch()
我正在尝试模拟类构造函数,但我还没弄明白要传递给@ mock.patch()装饰器的内容。文档说必须完全点缀(pyftdi.ftdi.Ftdi
),但where to patch
文档说该参数必须与被测试代码知道它的名称相匹配(Ftdi
)。我不知道如何满足两者。
为了使其具体,这是正在测试的文件:
from pyftdi.ftdi import Ftdi
class FtdiInterface(object):
@classmethod
def set_power(cls, url, on):
ftdi = Ftdi()
ftdi.open_from_url(url)
# ... do other things with ftdi
......和测试文件
import unittest
from unittest import mock
from ftdi_interface import FtdiInterface
import pyftdi.ftdi
class TestFtdiInterface(unittest.TestCase):
@mock.patch('pyftdi.ftdi.Ftdi')
def testPowerOn(self, MockFtdi):
url = 'some_string'
ftdi_instance = mock.MagicMock()
ftdi_instance.open_from_url = mock.MagicMock()
MockFtdi.return_value = ftdi_instance
FtdiInterface.set_power(url, True)
ftdi_instance.open_from_url.assert_called_with(url)
我观察到的是,尽管我试图修补Ftdi(),但对ftdi_instance.open_from_url()
的调用调用了库代码,而不是我的模拟对象。
我错过了什么?
答案
基本原则是修改查找对象的位置,该位置不一定与定义对象的位置相同。
这意味着对于mock
类Ftdi
,你必须提供一个路径到你的代码中Ftdi
实际实例化的地方。
要做到这一点,你需要用@mock.patch('pyftdi.ftdi.Ftdi')
替换@mock.patch('ftdi_interface.Ftdi')
:
import unittest
from unittest import mock
from ftdi_interface import FtdiInterface
class TestFtdiInterface(unittest.TestCase):
@mock.patch('ftdi_interface.Ftdi')
def testPowerOn(self, MockFtdi):
url = 'some_string'
ftdi_instance = mock.MagicMock()
ftdi_instance.open_from_url = mock.MagicMock()
MockFtdi.return_value = ftdi_instance
FtdiInterface.set_power(url, True)
ftdi_instance.open_from_url.assert_called_with(url)
线import pyftdi.ftdi
没有任何有用的测试,可以删除。
以上是关于嘲笑一个类:赶上22的主要内容,如果未能解决你的问题,请参考以下文章