如何模拟在我的 class 中使用 requests.get 的方法?
How do I mock a method that uses requests.get in my class?
我正在尝试为我的 class 创建一些单元测试。我想嘲笑这些,这样我就不会耗尽我的 API 配额 运行 其中一些测试。我有多个将调用 fetch
方法的测试用例,根据传递的 URL 我会得到不同的结果。
我的 示例 class 看起来像这样:
import requests
class ExampleAPI(object):
def fetch(self, url, params=None, key=None, token=None, **kwargs):
return requests.get(url).json() # Returns a JSON string
我正在查看的 tutorial 表明我可以做这样的事情:
import unittest
from mock import patch
def fake_fetch_test_one(url):
...
class TestExampleAPI(unittest.TestCase):
@patch('mymodule.ExampleAPI.fetch', fake_fetch_test_one)
def test_fetch(self):
e = ExampleAPI()
self.assertEqual(e.fetch('http://my.api.url.example.com'), """{'result': 'True'}""")
不过,当我这样做时,我收到一条错误消息:
TypeError: fake_fetch_test_one() takes exactly 1 argument (3 given)
在我的 class 的方法中模拟 requests.get
调用的正确方法是什么?我需要能够更改每次测试的模拟响应,因为不同的 URL 可以提供不同的响应类型。
通过您的测试方法,您可以对您的请求模块进行 monkeypatch
import unittest
class Mock:
pass
ExampleAPI.requests = Mock()
def fake_get_test_one(url):
/*returns fake get json */
ExampleAPI.requests.get= Mock()
ExampleAPI.requests.json = fake_get_test_one
class TestExampleAPI(unittest.TestCase):
def test_fetch(self):
e = ExampleAPI()
self.assertEqual(e.fetch('http://my.api.url.example.com'), """{'result': 'True'}""")
如果需要,您可以在测试的每个 setup() 和相应的 teardown() 方法中设置补丁 class
您的虚假提取需要接受与原始提取相同的参数:
def fake_fetch(self, url, params=None, key=None, token=None, **kwargs):
请注意,最好只模拟外部接口,这意味着让 fetch
调用 requests.get
(或者至少,它认为是 requests.get
):
@patch('mymodule.requests.get')
def test_fetch(self, fake_get):
# It would probably be better to just construct
# a valid fake response object whose `json` method
# would return the right thing, but this is a easier
# for demonstration purposes. I'm assuming nothing else
# is done with the response.
expected = {"result": "True"}
fake_get.return_value.json.return_value = expected
e = ExampleAPI()
self.assertEqual(e.fetch('http://my.api.url.example.com'), expected)
我正在尝试为我的 class 创建一些单元测试。我想嘲笑这些,这样我就不会耗尽我的 API 配额 运行 其中一些测试。我有多个将调用 fetch
方法的测试用例,根据传递的 URL 我会得到不同的结果。
我的 示例 class 看起来像这样:
import requests
class ExampleAPI(object):
def fetch(self, url, params=None, key=None, token=None, **kwargs):
return requests.get(url).json() # Returns a JSON string
我正在查看的 tutorial 表明我可以做这样的事情:
import unittest
from mock import patch
def fake_fetch_test_one(url):
...
class TestExampleAPI(unittest.TestCase):
@patch('mymodule.ExampleAPI.fetch', fake_fetch_test_one)
def test_fetch(self):
e = ExampleAPI()
self.assertEqual(e.fetch('http://my.api.url.example.com'), """{'result': 'True'}""")
不过,当我这样做时,我收到一条错误消息:
TypeError: fake_fetch_test_one() takes exactly 1 argument (3 given)
在我的 class 的方法中模拟 requests.get
调用的正确方法是什么?我需要能够更改每次测试的模拟响应,因为不同的 URL 可以提供不同的响应类型。
通过您的测试方法,您可以对您的请求模块进行 monkeypatch
import unittest
class Mock:
pass
ExampleAPI.requests = Mock()
def fake_get_test_one(url):
/*returns fake get json */
ExampleAPI.requests.get= Mock()
ExampleAPI.requests.json = fake_get_test_one
class TestExampleAPI(unittest.TestCase):
def test_fetch(self):
e = ExampleAPI()
self.assertEqual(e.fetch('http://my.api.url.example.com'), """{'result': 'True'}""")
如果需要,您可以在测试的每个 setup() 和相应的 teardown() 方法中设置补丁 class
您的虚假提取需要接受与原始提取相同的参数:
def fake_fetch(self, url, params=None, key=None, token=None, **kwargs):
请注意,最好只模拟外部接口,这意味着让 fetch
调用 requests.get
(或者至少,它认为是 requests.get
):
@patch('mymodule.requests.get')
def test_fetch(self, fake_get):
# It would probably be better to just construct
# a valid fake response object whose `json` method
# would return the right thing, but this is a easier
# for demonstration purposes. I'm assuming nothing else
# is done with the response.
expected = {"result": "True"}
fake_get.return_value.json.return_value = expected
e = ExampleAPI()
self.assertEqual(e.fetch('http://my.api.url.example.com'), expected)