sm1994
sm1994

Reputation: 355

Mocking a class in a Flask API

I have three files

helper.py

class helper:
    def __init__(self, out_file):
    self.out_file = out_file
    def foo(first, second):
        # Write data to file

flask_API.py

from helper import helper

@app.route('/', methods=['POST'])
def parse_request():
    content = request.get_json()

    out_file = #based on timestamp

    helper(out_file).foo(content['first'], content['second'])

test_flask.py

import unittest
from unittest.mock import patch
import flask_API

class testFlaskAPI(unittest.TestCase):
    def setUp(self):
        self.app = flask_API.app.test_client()
        self.app.test = True

    @patch('flask_API.app.helper', return_value=None)
    def test_service(self, mock_helper):
        response = self.app.post(base_url, data=json.dumps({"some":"value"}, content_type='application/json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

I am having trouble mocking the helper class. This gives me an error saying

AttributeError: <Flask 'flask_API'> does not have the attribute 'helper'

I read that a class/method needs to be mocked where it is being called instead of where it's defined. Is there something wrong with the way I am patching the class?

Upvotes: 1

Views: 2119

Answers (1)

sm1994
sm1994

Reputation: 355

In the end the solution turned out to be fairly simple. First there was no need to add app in the @patch decorator. The test just needed @patch('flask_API.helper'). Second, I first needed to return the mock of the class and then mock the function call as well. So the final answer turned out to be

@patch('flask_API.helper')
def test_service(self, mock_helper):

    mocking_helper = mock_helper.return_value  # mocking the class
    mocking_helper.foo.return_value = None

    response = self.app.post(base_url, data=json.dumps({"some":"value"}, content_type='application/json')
    self.assertEqual(response.status_code, status.HTTP_200_OK)

Upvotes: 1

Related Questions