如何模拟一个深度为两个导入的Python类,而不更改任何一个导入模块中的代码?假设我正在导入一个web实用程序库,它导入了一个HTTPClient()——我如何编写一个单元测试,模拟HTTPClient返回一个值,而不改变web文件呢_utils.py?我想在DataHandler中使用数据操作(而不是mockitout),但我不希望HTTPClient实际连接到web。在
这有可能吗?考虑到Python有monkey补丁,看起来应该如此。或者有其他/更好的方法吗?我还在弄明白嘲弄的过程,更不用说改变进口了。在
# someLib/web_utils.py
from abc.client import SomeHTTPClient # the class to replace
def get_client():
tc = SomeHTTPClient(endpoint='url') # fails when I replace the class
return tc
class DataHandler(object):
def post_data(someURL, someData):
newData = massage(someData)
client = get_client()
some_response = client.request(someURL, 'POST', newData)
return some_response
# code/myCode.py
from someLib.web_utils import DataHandler
dh = DataHandler()
reply = dh.post_data(url, data)
# tests/myTests.py
from django.test.testcases import TestCase
from mock import Mock
class Mocking_Test(TestCase):
def test_mock(self):
from someLib import web_utils
fakeClient = Mock()
fakeClient.request = web_utils.SomeHTTPClient.request # just to see if it works
web_utils.SomeHTTPClient = fakeClient
dh = DataHandler()
reply = dh.post_data(url='somewhere', data='stuff')
Update-添加了get_client()
函数。我认为@spicavigo的答案是正确的-它似乎正在替换SomeHTTPClient
类。但由于某些原因,类没有实例化对象(错误是,“must be type,not Mock”)。我也不明白它怎么可能是一个已经创建的Mock()
对象,而不是一个类。所以我不知道该怎么做。在
以下是最终奏效的方法:
在我最初的帖子中,我的思路是正确的,
patch
,我只是没有正确地进行补丁。另外,我没有替换整个类,而是只替换了类上的request
函数(这是所有需要模拟的,以避免实际发出HTTP请求)。在我知道这并不是您想要的,但是在创建了您的模拟类之后,我会简单地做一些类似的事情,以使代码更干净(在bashshell中,否则如果您有一个文件,您可以只执行查找和替换)
这应该会用新类替换旧类的所有实例,我个人认为这会使代码更简洁。如果只需要一个文件,而不是所有.py文件,只需将-name更改为“文件.py““
你能把这个加到我的测试.py试试看
相关问题 更多 >
编程相关推荐