python – 补丁 – 为什么相对补丁目标名称不会工作?
我从一个模块导入了一个类,但是当我尝试修补类名称而不将它作为前缀时,我得到一个类型错误:
TypeError: Need a valid target to patch. You supplied: 'MyClass' 例如,以下代码给出了以上错误: import unittest from mock import Mock,MagicMock,patch from notification.models import Channel,addChannelWithName,deleteChannelWithName,listAllChannelNames class TestChannel(unittest.TestCase): @patch("Channel") def testAddChannelWithNamePutsChannel(self,*args): addChannelWithName("channel1") Channel.put.assert_called_with() 虽然这个代码的第二个版本没有给我类型错误: import unittest from mock import Mock,listAllChannelNames class TestChannel(unittest.TestCase): @patch("notification.models.Channel") def testAddChannelWithNamePutsChannel(self,*args): addChannelWithName("channel1") Channel.put.assert_called_with() 这是为什么?为什么我可以在其他地方将Channel称为“Channel”,但是对于补丁,我需要模块前缀才能得到错误?此外,我有一种感觉,给予完整的模块前缀不工作,因为当我调用Channel.put.assert_called_with()我得到的错误,assert_called_with不是Channel.put的属性.有人可以解释发生了什么吗?非常感谢 解决方法
补丁装饰器要求目标是一个完整的虚线路径,如
documentation所述:
“Channel”只是一个字符串,而patch没有足够的信息来找到正确的类.这与您在其他地方使用的名称Channel不同,后者是在模块顶部导入的. 第二个测试失败,因为通道在测试模块中导入,然后修补程序使用mock对象替换notification.models中的Channel.什么补丁实际上是改变对象的名称通道在notification.models内使用指向.测试模块中的通道名称已经定义,因此不受影响.这实际上在这里更好地解释:http://www.voidspace.org.uk/python/mock/patch.html#id1 要访问对象的修补版本,您可以直接访问模块: import unittest from mock import patch from notification.models import Channel,addChannelWithName from notification import models class TestChannel1(unittest.TestCase): @patch("notification.models.Channel") def testAddChannelWithNamePutsChannel(self,*args): addChannelWithName("channel1") models.Channel.put.assert_called_with("channel1") 或者使用修补的版本作为额外的参数传递给装饰函数: class TestChannel2(unittest.TestCase): @patch("notification.models.Channel") def testAddChannelWithNamePutsChannel(self,mock_channel): addChannelWithName("channel1") mock_channel.put.assert_called_with("channel1") 如果您只想快速修补对象上的单一方法,通常更容易使用patch.object装饰器: class TestChannel3(unittest.TestCase): @patch.object(Channel,'put') def testAddChannelWithNamePutsChannel(self,*arg): addChannelWithName("channel1") Channel.put.assert_called_with("channel1") (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |