vendredi 11 septembre 2020

How can test Flask routes without internet connection with pytest, for integration test? How can I mock class called inside route?

I am doing a Flask application test with Pytest for integration test. I would like to test the routes in ‘view.py’. In routes in this ‘view.py’ I use function and class which parse a question from the front and a function which call an API with this parsed question. I would like to mock these classes in the ‘view.py’, but I don’t understand how to do, because this classes are not a parameter of ‘view.py’.

How can test, routes without internet connection? How can I mock class called inside route? 

I give some fake code to illustrate my problem. 

Thanks for your help.

Sébastien Jourdan

view.py:

from flask import Flask, jsonify, request, render_template
from parser_funciton import Parser
from call_API import CallApi

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("home.html")


@app.route('/conversation', methods=['POST'])
def conversation():

    if request.method == "POST":

        # Collect the question
        question = request.form["question"]
        print("La question : " + question)

        # Parse the question
        do_parser = Parser()
        parsed = do_parser.format_message(question)

        # Send the parsed question to an API
        call_api = CallApi()
        api_result = call_api.get_result_from_api(parsed)

        return jsonify({'question': parsed, 'results_api': api_result})


if __name__ == "__main__":
    app.run(debug=True)

parser_function.py:

class Parser:
    """ This class parse message from front input from user and return it to API"""

    @staticmethod
    def format_message(message_from_front):
        """Format message from front user input"""
        # Parse input message
        message_from_front = message_from_front.lower()
        message_from_front = message_from_front.replace(",", "")
        message_from_front = message_from_front.replace(".", "")
        message_from_front = message_from_front.strip()
        message_from_front = message_from_front.split(" ")

        return message_from_front

call_api.py:

import requests
import json

# GOOGLE_MAP_API_KEY = app.config['GOOGLE_MAP_API_KEY']


class CallApi:
    """ This class call API with parsed question parameter"""

    def get_result_from_api(self, title):
        """This function interogate the API Wiki Media to obtain coordinate from a title from an another function"""
        URL = "https://ffake.org/w/api.php"
        TITLES = title
        PARAMS = {
            "action": "query",
            "prop": "coordinates",
            "titles": TITLES,
            "format": "json"
        }
        data_coordinates = requests.get(url=URL, params=PARAMS)
        return data_coordinates

    

test_integration_view.py:

import pytest
import view
from view import app

    
@pytest.fixture
def client():
    app.config['TESTING'] = True

    with app.test_client() as client:
        yield client


class TestIntegrationView:
    """ Test get, post and route of application"""

    def setup_method(self):
        self.normal_to_post = "Hello . World ! ,"

    @staticmethod
    def test_view_home(client):
        assert client.get('/').status_code == 200

    def test_view(self, client):
        message_to_post = self.normal_to_post
        assert client.post('/conversation', data=dict(question=message_to_post)).status_code == 200

Aucun commentaire:

Enregistrer un commentaire