使用Pytest在函数中引发模拟异常 [英] Mock exception raised in function using Pytest

查看:112
本文介绍了使用Pytest在函数中引发模拟异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have the following function and it is a generic function which will make API call based on the input hostname and data. It will construct http request to make API and will return the response. This function will throw four types of exception(invalid URL, timeout, auth error and status check). How can I Mcok and Test the exception raised in API call using pytest? Which will be the best method to test the exceptions raised from API call?

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

我会收到类似以下的回复

i will get a response like following

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

推荐答案

您可以通过

You can mock error raising via side_effect parameter:

或者, side_effect 可以是异常类或实例.在这种情况下,调用模拟程序时将引发异常.

Alternatively side_effect can be an exception class or instance. In this case the exception will be raised when the mock is called.

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

In your case, this can be used like this (assuming call_api is defined in module 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' 

这篇关于使用Pytest在函数中引发模拟异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆