Can a Python mock object return the params it was given?

335 Views Asked by At

I am testing a Python method which makes an HTTP request to a server. The method looks like this:

def do_something():
    data = get_data()
    make_request(data)

def make_request(self, data):
    self.send_response(200)
    self.wfile.write(json.dumps(msg))

From my test, I want to assert based on the data variable. I don't want to touch the production code (i.e., I don't want to make the method return the data explicitly). Is there a way I can mock out the make_request method, but return the params as the return value? Something like:

service.make_request = MagicMock(return_value=params)
1

There are 1 best solutions below

1
On BEST ANSWER

If I understand correctly you want to test get_data() behavior in your production without change the code.

By mock framework you can use make_request(data) as sensor point and call_args to extract data (details at calls as tuples).

Simple example:

def extract_data(mock_make_request):
    """Helper function that return data passed to make_request() mock
    Check also if you have some calls and then reset it"""
    assert mock_make_request.called
    args, kwargs = mock_make_request.call_args
    mock_make_request.reset_mock()
    try:
        return kwargs['data']
    except TypeError:
        return args[0]

@patch("productioncodemodule.make_request")
def test_data(mock_make_request):
    """... your code that make do_something() call..."""
    data = extract_data(mock_make_request)
    """... your assert here..."""

There are too much details to cover here (patch decorator, reset_mock() and so on), but linked documentation should cover all of them.