gol*_*enk 19 python patch mocking
我从一个模块导入了一个类,但是当我尝试修补类名而没有它的模块作为前缀时,我得到一个类型错误:
TypeError: Need a valid target to patch. You supplied: 'MyClass'
Run Code Online (Sandbox Code Playgroud)
例如,以下代码给出了上述错误:
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()
Run Code Online (Sandbox Code Playgroud)
虽然这个代码的第二个版本没有给我类型错误:
import unittest
from mock import Mock, MagicMock, patch
from notification.models import Channel, addChannelWithName, deleteChannelWithName, listAllChannelNames
class TestChannel(unittest.TestCase):
@patch("notification.models.Channel")
def testAddChannelWithNamePutsChannel(self, *args):
addChannelWithName("channel1")
Channel.put.assert_called_with()
Run Code Online (Sandbox Code Playgroud)
这是为什么?为什么我可以在其他地方将Channel引用为"Channel",但对于补丁我需要模块前缀不会出错?另外,我觉得给出完整的模块前缀不起作用,因为当我调用Channel.put.assert_called_with()时,我得到的错误是assert_called_with不是Channel.put的属性.有人可以解释发生了什么吗?非常感谢!
Nic*_*tot 32
该patch装饰要求的目标是一个完整的虚线路径,如邮件中注明文档:
target应该是'package.module.ClassName'形式的字符串.导入目标并将指定的对象替换为新对象,因此目标必须可从您调用patch的环境中导入.执行修饰函数时导入目标,而不是在装饰时导入.
"Channel"只是一个字符串,并patch没有足够的信息来找到合适的类.这与Channel您在别处使用的名称不同,后者在模块顶部导入.
第二个测试失败,因为Channel在测试模块中导入,然后 patch使用模拟对象替换notification.models中的Channel.实际上做了什么补丁更改了在notification.models指向的Channel中使用的名称对象.测试模块中的名称Channel已经定义,因此不受影响.这实际上在这里有更好的解释: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")
Run Code Online (Sandbox Code Playgroud)
或者使用作为装饰函数的额外参数传递的修补版本:
class TestChannel2(unittest.TestCase):
@patch("notification.models.Channel")
def testAddChannelWithNamePutsChannel(self, mock_channel):
addChannelWithName("channel1")
mock_channel.put.assert_called_with("channel1")
Run Code Online (Sandbox Code Playgroud)
如果您只想快速修补对象上的单个方法,通常更容易使用patch.object装饰器:
class TestChannel3(unittest.TestCase):
@patch.object(Channel, 'put')
def testAddChannelWithNamePutsChannel(self, *arg):
addChannelWithName("channel1")
Channel.put.assert_called_with("channel1")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13209 次 |
| 最近记录: |