Flaskアプリでモックを使ったテスト方法!unittest.mockの活用例
生徒
「先生、Flaskのテストを書いてるときに、外部APIとかデータベースを使う部分をどうやってテストしたらいいのかわかりません…。」
先生
「とても良い質問だね。実は、そういうときには“モック(mock)”というテクニックを使うんだ。Pythonのunittest.mockモジュールを使えば、外部の処理を“ふり”だけすることができるんだよ。」
生徒
「ふりだけ?どういうことですか?」
先生
「たとえば、テスト中に本物のAPIを呼び出すと、お金がかかったり、遅かったりするよね。でもモックを使えば、APIを呼び出した“つもり”にして、テストをすぐに終わらせられるんだ。それでは実際にやってみよう!」
1. モック(mock)とは?
モックとは、テスト中に本物の処理の代わりをする「偽物のオブジェクト」のことです。Flaskのテストでよく使われる場面は次のようなケースです。
- 外部API(天気情報や決済システムなど)を呼び出す処理
- データベースアクセス
- メール送信
これらは実際に呼び出すと時間がかかったり、環境によって動作が違ったりします。そこでモックを使うと、外部との通信を行わずに「想定した結果」を返せるようになります。
2. unittest.mockとは?
unittest.mockは、Pythonに標準で用意されているモジュールです。特別なインストールは不要で、すぐに使うことができます。モックを作ることで、「この関数は呼び出されたか?」「どんな引数で呼ばれたか?」などを確認できます。
FlaskでAPIのテストをするときに、モックを使えば本物の通信を行わずにテストが可能になります。では、実際のサンプルを見てみましょう。
3. Flaskアプリの準備
まず、シンプルなFlaskアプリを作ります。このアプリは、天気APIからデータを取得して結果を返す簡単なものです。
# app.py
from flask import Flask, jsonify
import requests
app = Flask(__name__)
@app.route("/weather")
def get_weather():
response = requests.get("https://api.example.com/weather/tokyo")
data = response.json()
return jsonify({"city": "Tokyo", "temp": data["temp"]})
このコードは、外部APIhttps://api.example.comから天気情報を取得して返しています。でも実際にこのAPIを呼び出すのは、テスト中には避けたいですよね。ここで登場するのがモックです。
4. unittest.mockを使って外部APIをモックする
次に、requests.get()をモックしてテストを実行します。モックを使えば、実際にはAPIを呼ばずに、好きな値を返すようにできます。
# test_app.py
from app import app
from unittest.mock import patch
def test_get_weather():
with patch("app.requests.get") as mock_get:
mock_get.return_value.json.return_value = {"temp": 25}
client = app.test_client()
response = client.get("/weather")
assert response.status_code == 200
assert response.get_json() == {"city": "Tokyo", "temp": 25}
patch("app.requests.get")は、app.pyの中で使われているrequests.get()関数を一時的に置き換える(モックする)命令です。このようにして、APIを呼ばなくてもテストを実行できます。
5. 実行してみよう
ターミナルで次のコマンドを実行してみましょう。
pytest test_app.py
成功すると、次のような出力が表示されます。
============================= test session starts =============================
collected 1 item
test_app.py . [100%]
============================== 1 passed in 0.02s ==============================
これで、モックを使ったFlaskアプリのテストが成功しました。実際にはAPIを呼び出していませんが、テストとしては問題なく動作します。
6. モックを使うメリット
モックを使うと、Flaskアプリのテストをより安全かつ高速に行うことができます。主なメリットは以下の通りです。
- 外部APIに依存せずにテストできる
- 通信エラーやAPI制限を気にしなくていい
- テストが高速に実行できる
- 異常系(エラー発生時)のテストも簡単にできる
特に「APIの呼び出し制限がある」「ネット環境によって結果が変わる」ような場合でも、モックを使えば常に同じ結果でテストできるのが大きな利点です。
7. 少し発展的な例:エラーを返すモック
モックは成功パターンだけでなく、失敗パターンのテストにも使えます。たとえば、APIがエラーを返したときの挙動をテストしたい場合です。
from unittest.mock import patch
from app import app
def test_weather_api_error():
with patch("app.requests.get") as mock_get:
mock_get.side_effect = Exception("API Error")
client = app.test_client()
response = client.get("/weather")
assert response.status_code == 500
side_effectを使うと、モックに「例外を発生させる」動作を設定できます。これで、APIがエラーを返したときのアプリの挙動を確認できます。
8. 現場でも使われる実践テクニック
実際のFlask開発現場でも、モックは頻繁に使われます。特にCI/CD(自動テストとデプロイ)環境では、外部サービスを呼び出さずにテストを通すために必須のテクニックです。
また、patch()の代わりに@patchというデコレーターを使っても同じ効果が得られます。複数の外部関数をモックしたい場合に便利です。
from unittest.mock import patch
@patch("app.requests.get")
def test_with_decorator(mock_get):
mock_get.return_value.json.return_value = {"temp": 30}
client = app.test_client()
response = client.get("/weather")
assert response.get_json()["temp"] == 30
このように、モックを使えば外部依存のないテストが書けるようになり、Flaskアプリの品質を安定させることができます。
9. ポイント整理
Flaskでのモックを使ったテストは、外部APIやデータベースを実際に呼ばずにアプリの動作を確認するための強力な手法です。unittest.mockを使えば、Flaskのテストを簡単に自動化でき、アプリの品質を保ちながら開発スピードを上げることができます。
「テストの信頼性を高めたい」「外部サービスを使わずにテストをしたい」という人は、ぜひモックを使ってみましょう。
まとめ
Flaskアプリでモックを使ったテストを行う方法は、外部APIやデータベース、メール送信のような外部システムに依存する処理を安全かつ高速にテストするための重要な技術です。特にWebアプリのテストでは、ネットワーク環境や外部サービスの状態によって結果が左右されることが多く、安定したテストを行うにはモックの活用が欠かせません。モックによって「外部サービスを呼び出しているように見せかける」ことができるため、テストの完全性や再現性を高め、開発者が安心して機能追加やリファクタリングを進められる環境が整います。
また、Python標準ライブラリであるunittest.mockは、インストール不要で利用できるため、初心者でも簡単に導入できる点が魅力です。特にpatch()を使った関数の置き換えや、return_valueによる戻り値の指定、side_effectによる例外発生のシミュレーションなど、テストに欠かせない基本機能がひと通り揃っています。FlaskアプリでAPIを扱う際にも、requests.get()のような外部コールをモックするだけで、内部処理のテストに集中できるようになります。
さらに、モックを活用すると、エラーが発生したときの挙動をテストする「異常系テスト」がとてもやりやすくなります。たとえば、APIがタイムアウトしたり、予期せぬデータ形式を返したりしたときのアプリの反応を再現するのは、本物のAPIを使っては難しいですが、モックを使えば確実に再現できます。これにより、実際の運用環境でも安心して動作する強いアプリケーションを作ることにつながります。
Flaskとモックの組み合わせは、CI/CDなどの自動テスト環境でも非常に有効で、外部サービスの状態に依存せず安定したテストを実行できます。自動化パイプラインでテストが確実に成功するように設計することは、現代の開発において必須の要素であり、モックを理解しておくことは開発者としてのスキルアップにも直結します。
ここで、今回学んだ内容を整理しながら、簡単なサンプルコードを再掲して振り返りましょう。
外部APIをモックする基本コード
from app import app
from unittest.mock import patch
def test_get_weather():
with patch("app.requests.get") as mock_get:
mock_get.return_value.json.return_value = {"temp": 25}
client = app.test_client()
response = client.get("/weather")
assert response.status_code == 200
assert response.get_json() == {"city": "Tokyo", "temp": 25}
上記のコードでは、requests.get()をモックすることで、外部APIを本当に呼び出すことなくテストを実行しています。これによって、ネットワーク状態に依存しない安定したテストが可能になります。また、戻り値を自由に変更できるため、さまざまなケースを想定したテストが容易に書けるようになります。
一方で、異常な動作を故意に発生させたい場合、side_effectを活用して例外を発生させ、アプリのエラーハンドリングが正しく動作するかも確認できます。
エラーを再現するモックの例
from unittest.mock import patch
def test_weather_api_error():
with patch("app.requests.get") as mock_get:
mock_get.side_effect = Exception("API Error")
client = app.test_client()
response = client.get("/weather")
assert response.status_code == 500
このように、モックを使うことで、実際には起こりにくい状況を確実に再現してテストできるようになります。これがアプリの信頼性を高め、運用時の予期せぬトラブルを減らすことにつながります。 モックはFlaskアプリだけにとどまらず、Django、FastAPIなど、他のPythonフレームワークでも幅広く利用されている技術です。テストの自動化が必須となっている現代のWeb開発では、モックを理解して使いこなすことが極めて重要です。「外部サービスを実際に呼ばずにテストする」という発想を身につけるだけで、テストの質と効率が飛躍的に向上します。
生徒
「モックって難しいと思ってたけど、実際には“ふりをする”仕組みなんですね。これなら外部APIが動かなくても安心してテストできます!」
先生
「その通り。外部サービスはいつでも安定して動いているとは限らないから、テストではモックを使って“変わらない結果”を返すようにするといいんだ。」
生徒
「しかも、例外を投げるテストもできるのが驚きでした!エラーパターンのテストが楽になりますね。」
先生
「まさにそのとおり。モックを使うことで、成功ケースも失敗ケースも自由に再現できるから、Flaskアプリの信頼性がぐっと高まるんだよ。」
生徒
「これならテストがもっと楽しくなりそうです!CI/CDでも役立ちそうですね。」
先生
「うん、モックは現場でも必須の技術だから、ぜひ継続して使いながら慣れていこう。」