Reputation: 317
I have Flask views.py unit test that calls the other REST API. How can I specifically mock one of the requests?
The reason is one of the requests will trigger some operations, such as commit to database, overwrite to a file, etc, if the status code is 200. I want to check if the status code would return 200. If yes, I want to prevent the subsequent operations in unit test, and if not, it's not hitting any subsequent operation anyways so no worries.
I also want the mocked request does not affect the Flask app request at all, i.e. the Flask app request is not being mocked.
project/views.py
from flask import Flask
from project.another_dir.another_script import another_function
app = Flask(__name__)
@app.route('/api/abcde', methods=['POST'])
def post_something():
another_function()
project/another_dir/another_script.py
import requests
def another_function():
response = requests.post(<some_url>) # this is the "requests" I want to mock
if response.status_code == 200:
# server working properly, commit database transaction / write to a file / trigger some other functions / ...
else:
# something's wrong with the server, send error for exception handling
Unit test
from unittest.mock import Mock
import pytest
headers = {'Authorization': 'Basic akd39K045Pw=='}
data = "some_data"
@pytest.fixture
def client():
app.testing = True
client = app.test_client()
return client
@pytest.mark.parametrize("h, d, status_code", [
(None, None, 401), # no auth header, no data
(None, data, 401), # no auth header
(headers, data, 200) # with auth header and data
])
def test_views_post_something(client, h, d, status_code):
##### This is what I want to mock to avoid actually committing to db
# from project.another_dir.another_script import requests
# mock_request = Mock()
# requests = mock_request
##### But no luck
response = client.post('/api/abcde', headers=h, data=d)
assert response.status_code == status_code
Upvotes: 2
Views: 2031
Reputation: 806
Have you tried pook and unmock? They serve different use cases, but in this case it sounds like pook is a better fit. Pook works well if the request you're mocking will not change that much and is of a private/internal API
Another option is to use a tool like docker-compose
to spin up an ephemeral stack with your database of choice. That way, you can let the request execute without touching any fragile resources, but this tends to be slower and prone to errors if you are trying to recreate complicated states. I usually start with a more low-touch approach like pook
or unmock
and then build out an ephemeral stack for the most mission-critical tests.
Upvotes: 3