Mock exception raised in function using Pytest

大憨熊 提交于 2019-12-10 21:31:33

问题


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)

If i call this function

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>"

回答1:


You can mock error raising via side_effect parameter:

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

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' 


来源:https://stackoverflow.com/questions/50964786/mock-exception-raised-in-function-using-pytest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!