使用 python 模拟 urllib3.PoolManager().request 函数
Mocking urllib3.PoolManager().request function with python
我有一个函数可以使用 urllib3.PoolManager() 发出 POST 请求。现在在单元测试中我想模拟所述请求但有一些困难。正确的做法是什么?
我的代码:
http = urllib3.PoolManager()
# my func
def func(event, context):
...
resp = http.request('POST', url, body=encoded_msg)
...
# unit test
@patch('urllib3.PoolManager.request')
def test_lambda_handler(self, mock_instance):
mock_instance.return_value = Mock(status = "200", data = "success")
res = func(event, [])
mock_instance.request.assert_called_once()
我收到此错误“AssertionError:预期 'request' 已被调用一次。已调用 0 次。”
由于您在 全局(或模块)作用域 中调用了 urllib3.PoolManager
class 的构造函数。参考:#where-to-patch
module b
does import a
and some_function
uses a.SomeClass
. ... In this case the class we want to patch is being looked up in the module and so we have to patch a.SomeClass
instead: @patch('a.SomeClass')
选项 1:在模拟 urllib3.PoolManager
之后导入 func
class
lambda_handler.py
:
import urllib3
import json
http = urllib3.PoolManager()
print('http: ', http)
def func(event, context):
url = 'http://localhost:3000'
data = {'attribute': 'value'}
encoded_msg = json.dumps(data).encode('utf-8')
resp = http.request('POST', url, body=encoded_msg)
test_lambda_handler.py
:
import unittest
import json
from unittest import mock
class TestLambdaHandler(unittest.TestCase):
@mock.patch('urllib3.PoolManager')
def test_lambda_handler(self, mock_PoolManager):
from lambda_handler import func
mock_http = mock_PoolManager.return_value
event = {}
func(event, [])
mock_http.request.assert_called_once_with('POST', 'http://localhost:3000', body=json.dumps({'attribute': 'value'}).encode('utf-8'))
unittest.main(verbosity=2)
测试结果:
test_lambda_handler (__main__.TestLambdaHandler) ... http: <MagicMock name='PoolManager()' id='4475122928'>
ok
----------------------------------------------------------------------
Ran 1 test in 0.063s
OK
Name Stmts Miss Cover Missing
---------------------------------------------------------------------------------
src/Whosebug/69890084/lambda_handler.py 9 0 100%
src/Whosebug/69890084/test_lambda_handler.py 12 0 100%
---------------------------------------------------------------------------------
TOTAL 21 0 100%
方案二:mock全局变量http
,mock后不需要导入func
如果您在测试文件的顶部导入 lambda_handler
模块,模块 lambda_handler
将引用真实的 urllib3.PoolManager
,这样就来不及模拟了。
import unittest
import json
from unittest import mock
from lambda_handler import func
class TestLambdaHandler(unittest.TestCase):
@mock.patch('lambda_handler.http')
def test_lambda_handler(self, mock_http):
event = {}
func(event, [])
mock_http.request.assert_called_once_with('POST', 'http://localhost:3000', body=json.dumps({'attribute': 'value'}).encode('utf-8'))
unittest.main(verbosity=2)
测试结果:
http: <urllib3.poolmanager.PoolManager object at 0x1104b2610>
test_lambda_handler (__main__.TestLambdaHandler) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Name Stmts Miss Cover Missing
---------------------------------------------------------------------------------
src/Whosebug/69890084/lambda_handler.py 9 0 100%
src/Whosebug/69890084/test_lambda_handler.py 11 0 100%
---------------------------------------------------------------------------------
TOTAL 20 0 100%
我有一个函数可以使用 urllib3.PoolManager() 发出 POST 请求。现在在单元测试中我想模拟所述请求但有一些困难。正确的做法是什么?
我的代码:
http = urllib3.PoolManager()
# my func
def func(event, context):
...
resp = http.request('POST', url, body=encoded_msg)
...
# unit test
@patch('urllib3.PoolManager.request')
def test_lambda_handler(self, mock_instance):
mock_instance.return_value = Mock(status = "200", data = "success")
res = func(event, [])
mock_instance.request.assert_called_once()
我收到此错误“AssertionError:预期 'request' 已被调用一次。已调用 0 次。”
由于您在 全局(或模块)作用域 中调用了 urllib3.PoolManager
class 的构造函数。参考:#where-to-patch
module
b
doesimport a
andsome_function
usesa.SomeClass
. ... In this case the class we want to patch is being looked up in the module and so we have to patcha.SomeClass
instead:@patch('a.SomeClass')
选项 1:在模拟 urllib3.PoolManager
之后导入 func
class
lambda_handler.py
:
import urllib3
import json
http = urllib3.PoolManager()
print('http: ', http)
def func(event, context):
url = 'http://localhost:3000'
data = {'attribute': 'value'}
encoded_msg = json.dumps(data).encode('utf-8')
resp = http.request('POST', url, body=encoded_msg)
test_lambda_handler.py
:
import unittest
import json
from unittest import mock
class TestLambdaHandler(unittest.TestCase):
@mock.patch('urllib3.PoolManager')
def test_lambda_handler(self, mock_PoolManager):
from lambda_handler import func
mock_http = mock_PoolManager.return_value
event = {}
func(event, [])
mock_http.request.assert_called_once_with('POST', 'http://localhost:3000', body=json.dumps({'attribute': 'value'}).encode('utf-8'))
unittest.main(verbosity=2)
测试结果:
test_lambda_handler (__main__.TestLambdaHandler) ... http: <MagicMock name='PoolManager()' id='4475122928'>
ok
----------------------------------------------------------------------
Ran 1 test in 0.063s
OK
Name Stmts Miss Cover Missing
---------------------------------------------------------------------------------
src/Whosebug/69890084/lambda_handler.py 9 0 100%
src/Whosebug/69890084/test_lambda_handler.py 12 0 100%
---------------------------------------------------------------------------------
TOTAL 21 0 100%
方案二:mock全局变量http
,mock后不需要导入func
如果您在测试文件的顶部导入 lambda_handler
模块,模块 lambda_handler
将引用真实的 urllib3.PoolManager
,这样就来不及模拟了。
import unittest
import json
from unittest import mock
from lambda_handler import func
class TestLambdaHandler(unittest.TestCase):
@mock.patch('lambda_handler.http')
def test_lambda_handler(self, mock_http):
event = {}
func(event, [])
mock_http.request.assert_called_once_with('POST', 'http://localhost:3000', body=json.dumps({'attribute': 'value'}).encode('utf-8'))
unittest.main(verbosity=2)
测试结果:
http: <urllib3.poolmanager.PoolManager object at 0x1104b2610>
test_lambda_handler (__main__.TestLambdaHandler) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Name Stmts Miss Cover Missing
---------------------------------------------------------------------------------
src/Whosebug/69890084/lambda_handler.py 9 0 100%
src/Whosebug/69890084/test_lambda_handler.py 11 0 100%
---------------------------------------------------------------------------------
TOTAL 20 0 100%