Search code examples
testingflaskmockingflask-testing

Unable to mock api call inner Function in Flask Unitest


I am unable to mock API Calls function call in Flask Rest API Tests. I am using unittest and pytest module.

Code follows as:

rest_api.py


@app.route('/api/v1/recommender', methods=['POST'])
def recommender():
    """Handle POST requests that are sent to /api/v1/recommender REST API endpoint."""
    r = {'recommendation': 'failure', 'external_request_id': None}
    metrics_payload = {
        'pid': os.getpid(),
        'hostname': os.environ.get("HOSTNAME"),
        'endpoint': request.endpoint,
        'request_method': request.method,
        'status_code': 200
    }

    input_json = request.get_json()

        try:
            persist = request.args.get('persist', 'true') == 'true'
            r = RecommendationTask().execute(input_json, persist=persist,
                                             check_license=check_license)
        except Exception as e:
            r = {
                'recommendation': 'unexpected error',
                'external_request_id': input_json.get('external_request_id'),
                'message': '%s' % e
            }
            metrics_payload['status_code'] = 500

    return flask.jsonify(r), 200

test_rest_api.py

import pytest
from src.rest_api import app

@pytest.fixture
def client():
    """Provide the client session used by tests."""
    with app.test_client() as client:
        yield client

@mock.patch('src.recommender.RecommendationTask.execute', side_effect=None, return_result=None)
def test_recommendation_api_endpoint(_mock_object, client):
    """Check the /recommender REST API endpoint."""
    rec_resp = client.post(api_route_for("recommender"),
                           data=json.dumps(payload), content_type='application/json')

I am unable to Mock src.recommender.RecommendationTask.execute Function. Mocking works perfectly fine in Direct Function Tests but not in API Calls.

PS: By Direct Function calls, i mean Testing Function by importing and executing them rightaway in test scripts. Please help.


Solution

  • Solved this by creating another mocked function.

    class FakedResponse:
        """Fake Response2."""
    
        status_code = 200
    
        @staticmethod
        def json():
            """Json Response."""
            return response
    

    then Modifying actual test function by

    @mock.patch('src.recommender.RecommendationTask.execute', side_effect=None, return_result=None)
    def test_recommendation_api_endpoint(_mock_object, client):
        """Check the /recommender REST API endpoint."""
        r.cursor = FakedResponse()
    
        rec_resp = client.post(api_route_for("recommender"),
                               data=json.dumps(payload), content_type='application/json')