Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用requests\u mock来确保调用了正确的会话?_Python_Python 3.x_Unit Testing_Python Requests - Fatal编程技术网

Python 如何使用requests\u mock来确保调用了正确的会话?

Python 如何使用requests\u mock来确保调用了正确的会话?,python,python-3.x,unit-testing,python-requests,Python,Python 3.x,Unit Testing,Python Requests,我的情况与此类似: 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

我的情况与此类似:

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
调用,而不是重新使用同一个会话

但是,这意味着这样的测试实际上不会测试此功能:

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)
我曾经考虑过用mock替换self.session,但是我还必须在mock上设置status\u代码(在我的真实代码示例中,我还需要添加mock,以便代码正确使用响应函数)


有没有一种方法可以使用requests\u 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))
使用此模拟后,您可以访问
\u called\u 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)