【问题标题】:issue catching exception with unittest.mock.patch and requests使用 unittest.mock.patch 和 requests 捕获异常的问题
【发布时间】:2019-12-16 22:30:47
【问题描述】:

我遇到了测试问题,特别是使用 unittest.mock.patch 和 requests 模拟请求: 这是要测试的函数:

import os
from http import HTTPStatus

import requests
from requests.exceptions import RequestException

from .exceptions import APIException



logger = logging.getLogger("my_project")


def request_ouath2_token(dict_data, debugging=False):
    """
    request oauth2 token from COMPANY
    """
    api_endpoint = "{}/services/api/oauth2/token".format(
        dict_data['https_domain']
    )
    headers = {
        'Content-Type': 'application/json',
        'cache-control': 'no-cache'
    }
    data = {
        'clientId': dict_data['clientId'],
        'clientSecret': dict_data['clientSecret'],
        'grantType': 'client_credentials',
        'scope': 'all'
    }
    if debugging:
        logger.debug('COMPANY AUTH API: {}'.format(api_endpoint))
    response = requests.post(api_endpoint, json=data, headers=headers)
    try:
        response.raise_for_status()
    except RequestException as _e:
        raise APIException("error on requesting a new OAuth2 access token, error: {}".format(str(_e)))
    content = response.json()
    return content

这是测试:

# test module

import os
import unittest
import warnings
from unittest.mock import patch, Mock
import json
from http import HTTPStatus

from myapp.api import auth, exceptions as api_exceptions



class AuthHelpersTestCase(unittest.TestCase):
    """
    auth test helper class
    """
    def setUp(self):
        self.secret = "my secret"
        self.decoded_secret = base64.b64decode(self.secret)
        self.token = "my token"
        self.url = "/my/relative/url"
        self.user = "my user"
        self.portal = "my-portal"
        self.api_key = "my api key"
        self.oauth2_client_id = "my ouath2 client id"
        self.oauth2_client_secret = "my ouath2 client secret"
        self.oauth2_token_exp_secs = 3600
        self.oauth2_obtained_access_token = 'obtained-oauth2-access-token'
        self.alias = '{}_{}'.format(self.user, int(datetime.utcnow().strftime("%s")))


    def test_request_ouath2_token_failure(self):
        with patch('requests.post') as mock_request:
            rsp_content, data_dict = self._mock_request_ouath2_token_config()
            mock_response = Mock()
            mock_response.status_code = HTTPStatus.UNAUTHORIZED.value
            mock_response.content = json.dumps(rsp_content)
            mock_request.return_value = mock_response
            with self.assertRaises(api_exceptions.APIException) as cm:
                auth.request_ouath2_token(data_dict)
                self.assertEqual(cm.exception, api_exceptions.APIException)

似乎我的函数中没有引发异常,除了模拟的响应状态码是 500;似乎 raise_for_status() 没有抓住它。

结果:

======================================================================
ERROR: test_request_ouath2_token_failure (tests.test_auth.AuthHelpersTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/myuser/PycharmProjects/company/tests/test_auth.py", line 165, in test_request_ouath2_token_failure
    self.assertEqual(cm.exception, api_exceptions.APIException)
AttributeError: '_AssertRaisesContext' object has no attribute 'exception'

知道为什么吗?我错过了什么吗?

【问题讨论】:

  • 如果您的代码甚至达到了那一步,那么它不会引发任何异常。因为一个异常已经把你踢出 with 块了。
  • 您的厘米,实际上没有任何称为异常的方法。您可以使用cm.__dict__.keys()dir(cm) 列出所有方法。可以贴.exception的源码吗?
  • @LucasVazquez 是的,cm.__dict__ 中没有 exception 键。但是,如果我在request_ouath2_token 中手动提出APIException,则测试通过。

标签: python python-requests python-unittest python-mock


【解决方案1】:
  1. 当您使用assertRaises 的返回值作为上下文管理器时,您应该在块外检查结果。请记住,您是在断言应该引发异常。
  2. 在您的代码中达到了self.assertEqual(cm.exception, api_exceptions.APIException),因为它之前的行没有引发异常。
  3. 尝试在request_ouath2_token 中尝试print(requests.post),如果您没有看到模拟对象,则意味着您的修补不起作用。如果包含request_ouath2_token 的模块称为x_mod,则应尝试使用patch.object(x_mod.requests, "post") 之类的内容对其进行修补。

【讨论】:

    猜你喜欢
    • 2011-03-16
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    相关资源
    最近更新 更多