我在foo.py中有一个类,我想测试:
import requests
class Foo:
def fooMethod(self, url):
response = requests.get(url)
return response我想替换requests调用来模拟响应。
这是我的test_foo.py测试文件
from foo import Foo
def mocked_requests_get(*args, **kwargs):
class MockResponse:
def __init__(self, text, code):
self.text = text
self.code = code
if args[0] == "http://localhost":
return MockResponse("Test response", 200)
return MockResponse(None, 404)
class TestFoo:
def test_foo(self, mocker):
a = Foo()
mocker.patch ('foo.requests.get', mocked_requests_get)
spy = mocker.spy (a, 'test_foo.mocked_requests_get')
response = a.fooMethod("http://localhost")
assert response.text == "Test response"
assert spy.call_count == 1我想检查是否只调用了一次mocked_requests_get函数。
解释器在spy = mocker.spy ...行上出现一个错误:
'Foo' object has no attribute 'test_foo.mocked_requests_get'这是可以理解的--但我无法找到引用该函数的对象实例。有人能帮忙吗?
发布于 2021-02-26 14:26:25
您的方法有点复杂-您可以只使用一个标准模拟,而不需要实现您自己的模拟类。像这样的事情应该有效:
class TestFoo:
def test_foo(self, mocker):
a = Foo()
get_mock = mocker.patch('requests.get')
get_mock.return_value.text = "Test response"
response = a.fooMethod()
assert response.text == "Test response"
assert get_mock.call_count == 1还要注意,您必须修补requests.get而不是foo.requests.get,因为您直接导入了requests (参见打补丁的地方)。
更新:
如果需要响应依赖于url,如更新的问题中所示,可以使用side_effect,它可以接受函数或类对象(除非return_value需要一个求值的值):
class MockedResponse:
def __init__(self, url):
self.url = url
@property
def text(self):
responses = {"url1": "response1",
"url2": "response2",
"url3": "response3"}
if self.url in responses:
return responses[self.url]
return "default"
class TestFoo:
def test_foo(self, mocker):
a = Foo()
get_mock = mocker.patch('requests.get')
get_mock.side_effect = MockedResponse
response = a.fooMethod("url2")
assert response.text == "response2"
assert get_mock.call_count == 1https://stackoverflow.com/questions/66387081
复制相似问题