gpt4 book ai didi

python - 如何使用 requests_mock 来确保调用正确的 session ?

转载 作者:太空宇宙 更新时间:2023-11-03 15:00:14 24 4
gpt4 key购买 nike

我有一个类似的情况:

import unittest
import requests_mock
import requests

import mock

class ClassUnderTest:
def __init__(self):
self.session = requests.Session()
self.foo_url = 'http://google.com'

def do_foo(self):
return self.session.get(self.foo_url)

def do_foo_failing(self):
# I want to prevent accidentally doing this sort of operation
# instead of reusuing self.session
return requests.get(self.foo_url)

我想确保这些方法正确执行,但也要确保我使用的是 self.session 对象。在实践中,我遇到了这个问题,因为我错误地添加了 requests.get 调用,而不是重新使用相同的 session 。

但这意味着这样的测试实际上并没有测试此功能:

class TestClassUnderTest(unittest.TestCase):

@requests_mock.mock()
def test_do_foo_should_pass(self, m):
c = ClassUnderTest()

m.get('http://google.com', status_code=200)
r = c.do_foo()

self.assertEqual(200, r.status_code)
self.assertEqual(m.call_count, 1)

@requests_mock.mock()
def test_do_foo_should_fail(self, m):
c = ClassUnderTest()
m.get('http://google.com', status_code=200)
r = c.do_foo_failing()

self.assertEqual(200, r.status_code)
self.assertEqual(m.call_count, 1)

我曾考虑过用模拟替换 self.session ,但随后我还必须在模拟上执行诸如设置 status_code 之类的操作(在我的真实代码示例中,我还需要执行诸如添加模拟 .json() method 以便使用响应的代码正确运行)。

有没有办法使用requests_mock来有效保证只使用self.session(而不是本例中的requests.get)?

最佳答案

以下工作原理是将所有 request.Session 函数包装到 MockClass,并使用跟踪它们的使用情况的包装器:

class MockSession:
def __init__(self):
self.session = requests.Session()
self._called_methods = {}

def session_decorator(f):
def func(*args, **kwargs):
if f.__name__ not in self._called_methods:
self._called_methods[f.__name__] = 1
else:
self._called_methods[f.__name__] += 1
return f(*args, **kwargs)
return func

for name, f in inspect.getmembers(self.session):
if inspect.ismethod(f):
setattr(self, name, session_decorator(f))

使用此模拟后,您可以访问 ._used_methods 值来检查调用各个方法的频率。请注意,由于 requests_mock 的工作原理,您必须在运行时执行此操作(而不是通过简单地扩展具有类似功能的 requests.Session 类来加载时)。

修改测试代码结果:

class TestClassUnderTest(unittest.TestCase):

@requests_mock.mock()
def test_do_foo_should_pass(self, m):
c = ClassUnderTest()
c.session = MockSession()
m.get('http://google.com', status_code=200)
r = c.do_foo()

self.assertEqual(200, r.status_code)
self.assertEqual(m.call_count, 1)
self.assertEqual(c.session._called_count['GET'], 1)

@requests_mock.mock()
def test_do_foo_should_fail(self, m):
c = ClassUnderTest()
c.session = MockSession()
m.get('http://google.com', status_code=200)
r = c.do_foo_failing()

self.assertEqual(200, r.status_code)
self.assertEqual(m.call_count, 1)

# This will fail with an attribute error
# because that function was never invoked on the mock session
self.assertEqual(c.session._called_count['GET'], 1)

关于python - 如何使用 requests_mock 来确保调用正确的 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45174779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com