Hus*_*ain 6 python unit-testing urllib2 python-mock
下面是我的api.py模块的代码片段
# -*- coding: utf-8 -*-
from urllib2 import urlopen
from urllib2 import Request
class API:
def call_api(self, url, post_data=None, header=None):
is_post_request = True if (post_data and header) else False
response = None
try:
if is_post_request:
url = Request(url = url, data = post_data, headers = header)
# Calling api
api_response = urlopen(url)
response = api_response.read()
except Exception as err:
response = err
return response
Run Code Online (Sandbox Code Playgroud)
我试图嘲弄urllib2.urlopen
在unittest
上述模块.我已经写了
# -*- coding: utf-8 -*-
# test_api.py
from unittest import TestCase
import mock
from api import API
class TestAPI(TestCase):
@mock.patch('urllib2.Request')
@mock.patch('urllib2.urlopen')
def test_call_api(self, urlopen, Request):
urlopen.read.return_value = 'mocked'
Request.get_host.return_value = 'google.com'
Request.type.return_value = 'https'
Request.data = {}
_api = API()
assert _api.call_api('https://google.com') == 'mocked'
Run Code Online (Sandbox Code Playgroud)
运行unittest后,我得到一个例外
<urlopen error unknown url type: <MagicMock name='Request().get_type()' id='159846220'>>
Run Code Online (Sandbox Code Playgroud)
我错过了什么?请帮帮我.
你正在修补错误的东西:看看补丁的位置.
在api.py
通过
from urllib2 import urlopen
from urllib2 import Request
Run Code Online (Sandbox Code Playgroud)
您创建一个本地引用urlopen
,并Request
在文件中.通过mock.patch('urllib2.urlopen')
要修补原来的参考和离开api.py
的一个不变.
所以,替换你的补丁
@mock.patch('api.Request')
@mock.patch('api.urlopen')
Run Code Online (Sandbox Code Playgroud)
应该解决你的问题....但还不够.
在您的测试情况下api.Request
不使用,但urllib2.urlopen()
创建一个Request
通过使用修补版本:这就是为什么Request().get_type()
是MagicMock
.
要获得完整的修复,您应该根据需要更改测试.首先是代码:
@mock.patch('api.urlopen', autospec=True)
def test_call_api(self, urlopen):
urlopen.return_value.read.return_value = 'mocked'
_api = API()
self.assertEqual(_api.call_api('https://google.com'), 'mocked')
urlopen.assert_called_with('https://google.com')
Run Code Online (Sandbox Code Playgroud)
现在澄清......在你的测试中你没有调用Request()
因为你只传递了第一个参数,所以我删除了无用的补丁.此外,您正在修补urlopen
函数而不是urlopen
对象,这意味着read()
您想要模拟的方法是对象通过urlopen()
调用返回的方法.
最后,我添加了一个urlopen
电话检查,autospec=True
这总是一个很好的做法.
归档时间: |
|
查看次数: |
2680 次 |
最近记录: |