我正在尝试使用Pythons mock包来模拟Pythons requests模块.让我在以下场景中工作的基本要求是什么?
在我的views.py中,我有一个函数可以使每次request.get()调用具有不同的响应
def myview(request):
res1 = requests.get('aurl')
res2 = request.get('burl')
res3 = request.get('curl')
Run Code Online (Sandbox Code Playgroud)
在我的测试类中,我想做类似的事情,但无法弄清楚确切的方法调用
步骤1:
# Mock the requests module
# when mockedRequests.get('aurl') is called then return 'a response'
# when mockedRequests.get('burl') is called then return 'b response'
# when mockedRequests.get('curl') is called then return 'c response'
Run Code Online (Sandbox Code Playgroud)
第2步:
打电话给我
第3步:
验证响应包含'响应','b响应','c响应'
如何完成步骤1(模拟请求模块)?
我有一段代码,我无法弄清楚如何进行单元测试!该模块使用urllib2从外部XML提要(twitter,flickr,youtube等)中提取内容.这是一些伪代码:
params = (url, urlencode(data),) if data else (url,)
req = Request(*params)
response = urlopen(req)
#check headers, content-length, etc...
#parse the response XML with lxml...
Run Code Online (Sandbox Code Playgroud)
我的第一个想法是挑选响应并加载它以进行测试,但显然urllib的响应对象是不可序列化的(它引发了异常).
仅仅从响应主体保存XML并不理想,因为我的代码也使用了头信息.它旨在作用于响应对象.
当然,在单元测试中依赖外部数据来源是一个可怕的想法.
那么我该如何为此编写单元测试呢?
我想在python中伪造一个包.我想定义一些代码可以做的事情
from somefakepackage.morefakestuff import somethingfake
Run Code Online (Sandbox Code Playgroud)
并且somefakepackage在代码中定义,因此它下面的所有内容都是如此.那可能吗?这样做的原因是欺骗我的单元测试我得到了一个包(或者我在标题中说的一个模块)在python路径中实际上只是为这个单元测试模拟的东西.
谢谢!
我试图以一种方式模拟urllib2.urlopen库,我应该为我传递给函数的不同URL获得不同的响应.
我现在在我的测试文件中这样做的方式是这样的
@patch(othermodule.urllib2.urlopen)
def mytest(self, mock_of_urllib2_urllopen):
a = Mock()
a.read.side_effect = ["response1", "response2"]
mock_of_urllib2_urlopen.return_value = a
othermodule.function_to_be_tested() #this is the function which uses urllib2.urlopen.read
Run Code Online (Sandbox Code Playgroud)
我希望othermodule.function_to_be_tested在第一次调用时获得值"response1",在第二次调用时获得"response2",这是side_effect将执行的操作
但是othermodule.function_to_be_tested()收到了
<MagicMock name='urlopen().read()' id='216621051472'>
Run Code Online (Sandbox Code Playgroud)
而不是实际的反应.请告诉我出错的地方或更简单的方法.
我有一个棘手的问题,我似乎无法掌握.我目前正在为django自定义auth-backend编写单元测试.在我们的系统上,我们实际上有两个后端:一个是内置的django后端和一个自定义后端,它向基于Java的API发送请求,该API以XML的形式返回用户信息.现在,我正在编写单元测试,所以我不想在系统之外发送请求,我不是要尝试测试Java API,所以我的问题是如何解决这个问题并模拟副作用以最强大的方式.
我正在测试的函数是这样的,其中url设置值只是Java服务器的基本URL,用于验证用户名和密码数据并返回xml,服务值只是构建url查询的一些魔力,它对我们不重要:
@staticmethod
def get_info_from_api_with_un_pw(username, password, service=12345):
url = settings.AUTHENTICATE_URL_VIA_PASSWORD
if AUTH_FIELD == "username":
params = {"nick": username, "password": password}
elif AUTH_FIELD == "email":
params = {"email": username, "password": password}
params["service"] = service
encoded_params = urlencode([(k, smart_str(v, "latin1")) for k, v in params.items()])
try:
# get the user's data from the api
xml = urlopen(url + encoded_params).read()
userinfo = dict((e.tag, smart_unicode(e.text, strings_only=True))
for e in ET.fromstring(xml).getchildren())
if "nil" in userinfo:
return userinfo
else:
return None
Run Code Online (Sandbox Code Playgroud)
因此,我们获取xml,将其解析为dict,如果key nil存在,那么我们可以返回dict并继续执行happy and authenticated.显然,一个解决方案就是找到一种方法以某种方式覆盖或monkeypatch …
我真的很喜欢Ruby中的fakeweb在测试时用来伪造http请求的方式.是否有类似的库或Python的替代品?
pyfakefs 听起来非常有用:它"最初是作为核心Python模块的适度伪造实现而开发的,用于支持中等复杂的文件系统交互,并于2006年9月在全谷范围内推出.从那时起,它已经收到了很多(经过充分测试) )扩展其功能和实用性的贡献,并用于900多个Google Python测试."
文档似乎目前仅在源代码本身的文档字符串中可用.它解释说该模块提供以下元素:
但是,文档没有解释如何在测试中有效地使用这些元素.
确保被测模块访问虚假文件系统而不是真实文件系统的正确方法是什么?
我有一个自定义框架,它为不同的客户端运行不同的代码。我对某些方法进行了猴子修补,以便为客户定制功能。
这是简化的模式:
#import monkeypatches here
if self.config['client'] == 'cool_dudes':
from app.monkeypatches import Stuff
if self.config['client'] == 'cool_dudettes':
from app.monkeypatches import OtherStuff
Run Code Online (Sandbox Code Playgroud)
这是一个补丁示例:
from app.framework.stuff import Stuff
def function_override(self):
return pass
Stuff.function = function_override
Run Code Online (Sandbox Code Playgroud)
当程序以批处理方式执行时,这种方法效果很好,每次都从头开始旋转。然而,当运行单元测试时,我发现猴子补丁在测试中持续存在,导致意外的行为。
我意识到使用面向对象的继承方法来进行这些重写会好得多,但我继承了这个代码库,并且目前无权重新构建它到那种程度。
除非正确地重新构建程序,否则如何防止这些猴子补丁在单元测试中持续存在?