Search code examples
pythonmockingpytestpatch

Pytest mock / patch of an api call


I am trying to understand patching, but I seem to be failing to do so.

Currently I am trying to patch an api call inside of the tested function:

# function being tested
def tested_function():
   response = call_to_api()
   status = response["status"]
   if status == "something":
   # some more logic to test

In the test_file.py I attempt to do the following:

@patch("import_from_same_file.call_to_api")
def test_tested_function(my_mock):
    my_mock.return_value = {"status":"COMPLETE"}

All I've been able to achieve so far is Got error: list indices must be integers or slices, not str error with no clue where is it actually coming from. Please help, already spent so many hours on this.

I have also tried to supply an object as a return value of the mock.

class Response():
   status = "COMPLETE"

With no luck though. Apparently I am missing something about how the patching works.


Solution

  • It's hard to say exactly what is going wrong, without seeing the call stack, but the following general pattern works.

    foo.py

    def foo():
        pass
    
    
    def bar():
        result = foo()
        return result["status"]
    

    The with test_foo.py as

    import mock
    
    from foo import bar
    
    
    @mock.patch("foo.foo", return_value={"status": "PASSED"})
    def test_add(mock_foo):
        assert bar() == "PASSED"
    

    This general pattern works with pytest test_foo.py in the same directory.