0

I have a function that makes an API call, and I would like to make the return value (response) of that API call to be {"message":"NoPong"} so that the ValueError would be raised. So far, I have

# root_folder/subfolder/includes/abc/functions.py

from abc import ABC   # 3rd party library

def _check_connection(conn_id):
    api_key = get_api_key(conn_id)  
    api_client = ABC(api_key=api_key)
    
    response = api_client.test_connection()
    print(response)
    
    if response['message'] != "pong":   
        raise ValueError("Failed connection to ABC")

---------------

# root_folder/tests/test_functions.py

import pytest
import sys
sys.path.insert(0, '../subfolder/')
from includes.abc.functions import _check_connection

def test_check_connection_raiseError(mocker):
    with pytest.raises(ValueError) as execinfo:  
        mocker.patch('includes.abc.functions.ABC.test_connection', return_value='{"message":"NoPong"}')
        _check_connection("conn_A")
    assert str(execinfo.value) == 'Failed connection to ABC'

The pytest results I got was

================================================== FAILURES ==================================================
______________________________________ test_check_connection_raiseError ______________________________________

mocker = <pytest_mock.plugin.MockerFixture object at 0x7f85f30c7220>

    def test_check_connection_raiseError(mocker):
        with pytest.raises(ValueError) as execinfo:
            mocker.patch('includes.abc.functions.ABC.test_connection', return_value='{"message":"NoPong"}')
            
>           _check_connection("conn_A")

test_functions.py:73: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

conn_id = 'conn_A'

    def _check_connection(conn_id):
        api_key = get_api_key(conn_id)
        api_client = ABC(api_key=api_key)
    
        response = api_client.test_connection()
        print(response)
    
>       if response['message'] != "pong":
E    TypeError: string indices must be integers

../subfolder/includes/abc/functions.py:70: TypeError
-------------------------------------------- Captured stdout call --------------------------------------------
{"message":"NoPong"}
========================================== short test summary info ===========================================
FAILED test_functions.py::test_check_connection_raiseError - TypeError: string indices must be integers

Why is pytest complaining about my _check_connection function? It is correctly accessing the dictionary with key message, and it works outside of pytest.

Rayne
  • 14,247
  • 16
  • 42
  • 59
  • 1
    Your patch string does not look right. `test_connection` is a function in `ABC`, so you probably need to patch `function.ABC` and assign the desired value to `mocked_abc.return_value.test_connection.return_value`. – MrBean Bremen Jul 29 '21 at 10:55

1 Answers1

1

You need to return a dictionary and not a string, so mocker.patch('includes.abc.functions.ABC.test_connection', return_value='{"message":"NoPong"}') should become: mocker.patch('includes.abc.functions.ABC.test_connection', return_value={"message":"NoPong"})

Without the quotes.

Peter K
  • 1,959
  • 1
  • 16
  • 22