简体   繁体   English

使用 unittest.mock.patch 和请求捕获异常

[英]issue catching exception with unittest.mock.patch and requests

I have an issue with tests, specifically with mocking a request with unittest.mock.patch and requests: this is the function to test:我有一个测试问题,特别是用 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

and this is the test:这是测试:

# 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)

it seems that the exception is not raised in my function, besides the mocked response status code is 500;除了模拟的响应状态代码是 500 之外,似乎我的函数中没有引发异常; it seems that raise_for_status() does not catch it.似乎 raise_for_status() 没有抓住它。

result:结果:

======================================================================
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'

any idea of why?知道为什么吗? am I missing something?我错过了什么吗?

  1. When you use the returned value of assertRaises as a context manager, you should check the result outside the block.当您使用assertRaises的返回值作为上下文管理器时,您应该检查块外的结果。 Remember, you are asserting that an exception should be raised.请记住,您是在断言应该引发异常。
  2. In your code self.assertEqual(cm.exception, api_exceptions.APIException) was reached because the line before it didn't raise an exception.在您的代码self.assertEqual(cm.exception, api_exceptions.APIException) ,因为它之前的行没有引发异常。
  3. Try to print(requests.post) in request_ouath2_token , if you don't see a mock object it means your patching doesn't work.尝试在request_ouath2_token print(requests.post) ,如果您没有看到模拟对象,则意味着您的修补不起作用。 If the module containing request_ouath2_token is called x_mod , you should try to patch it with something like patch.object(x_mod.requests, "post") .如果包含request_ouath2_token的模块被称为x_mod ,你应该尝试用类似patch.object(x_mod.requests, "post")东西修补它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM