【问题标题】:Mock exception raised in function using Pytest使用 Pytest 在函数中引发的模拟异常
【发布时间】:2018-06-21 09:15:33
【问题描述】:

我有以下函数,它是一个通用函数,它将根据输入的主机名和数据进行 API 调用。它将构造http请求以制作API并返回响应。此函数将抛出四种类型的异常(无效 URL、超时、身份验证错误和状态检查)。如何使用 pytest 测试和测试 API 调用中引发的异常?哪种方法是测试 API 调用引发的异常的最佳方法?

import ssl
import urllib
import urllib.request
import urllib.error
import xml
import xml.etree.ElementTree as ET

def call_api(hostname, data):
    '''Function to make API call
    '''
    # Todo:
    # Context to separate function?
    # check response for status codes and return reponse.read() if success
    #   Else throw exception and catch it in calling function
    error_codes = {
         "1": "Unknown command",
         "6": "Bad Xpath",
         "7": "Object not present",
         "8": "Object not unique"
     }
    url = "http://" + hostname + "/api"
    encoded_data = urllib.parse.urlencode(data).encode('utf-8')
    try:
        response = urllib.request.urlopen(url, data=encoded_data, 
timeout=10).read()
        root = ET.fromstring(response)
        if root.attrib.get('status') != "success":
            Errorcode = root.attrib.get('code')
            raise Exception(pan_error_codes.get(Errorcode, "UnknownError"), 
response)
        else:
            return response
    except urllib.error.HTTPError as e:
        raise Exception(f"HttpError: {e.code} {e.reason} at {e.url}", None)
    except urllib.error.URLError as e:
       raise Exception(f"Urlerror: {e.reason}", None)

如果我调用这个函数

def create_key(hostname, username, password):
hostname = 'myhost ip'
data = {
    'type': 'keygen',
    'username': username,
    'password': password
}
username = 'myuser'
password = 'password'
response = call_api(hostname, data)
return response

我会收到如下回复

b"<response status = 'success'><result><key>mykey</key></result></response>"

【问题讨论】:

    标签: python-3.x exception mocking urllib pytest


    【解决方案1】:

    您可以通过side_effect 参数模拟错误引发:

    另外,side_effect 可以是异常类或实例。在这种情况下,调用 mock 时会引发异常。

    在您的情况下,可以这样使用(假设 call_api 在模块 foo 中定义):

    import pytest
    from unittest.mock import patch
    
    def test_api():
        with patch('foo.call_api', side_effect=Exception('mocked error')):
            with pytest.raises(Exception) as excinfo:
                create_key('localhost:8080', 'spam', 'eggs')
            assert excinfo.value.message == 'mocked error' 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 1970-01-01
      • 2019-11-07
      • 1970-01-01
      相关资源
      最近更新 更多