
AIにモック・スタブを書かせる|テストが嘘をつかない確認
「テストは全部緑です」と朝会で報告した日の午後に、本番でだけ落ちる。ログをたどっていくと、外部サービスから返ってきた項目の名前が、こちらの想定と一文字だけ違っていた——そんな一日を過ごしたことのある人は、たぶん少なくありません。
しかもこういうとき、テストは何も教えてくれません。赤くならないどころか、直したあとも緑のままです。責める先がないぶん、じわっと消耗します。
モックやスタブ(=本物の代わりに決まった応答を返す代役のこと)をAIに頼むと、それらしいものが一瞬で揃います。ここは本当に速い。ただ、AIが書いているのは「本物」ではなく、「本物はこうなっているはず」という推測です。この記事では、その推測が現実とズレていないかを確かめる手順を、一緒に整理します。
結論:AIに書かせたモック・スタブは、次の3点だけ見れば大きな事故はかなり減らせます。①本物の応答を1件だけ実際に見てから作らせる——形の食い違いは、ここでほぼ止まります。②成功だけでなく、失敗・空・想定外の形も返させる。AIは何も言わないと、いつも成功する代役を書きます。③本物とズレたときに気づく細い1本を置く。モックは放っておくと、本物が変わっても永遠に昔の顔をし続けます。
3つ同時にやらなくて大丈夫です。まずは①だけでも、「テストは緑なのに本番で落ちる」のいちばん多い型は減らせます。
何が起きているのか——モックは「本物」ではなく「思い込み」を写している

まず、なぜAIのモックが実物とズレるのかを共有させてください。理由は3つあります。
1つ目は、AIが本物を見ていないこと。「この外部APIを呼ぶ部分のテストを書いて」と頼むと、AIは学習した一般的な形から「たぶんこういう応答だろう」を組み立てます。図の左のように、本物の応答を1件見せていない限り、そこにあるのは推測です。よくある形には合っているので、それらしく見えてしまうのが厄介なところでもあります。
2つ目は、テストを通すことが目的になりやすいこと。頼まれているのは「テストを書く」ことなので、通る側の道が組み上がります。代役はいつも成功を返し、遅れず、落ちない。現場でいちばん怖いのは、その反対側なのですが、聞かれていないので出てきません。ハッピーパス(=全部うまくいく道筋)に寄る性質は、AIにテストケースを洗い出させる|観点の与え方で扱った話とまったく同じ根っこです。
3つ目は、モックは一度書くと誰も見直さないこと。本物のサービスは、こちらの都合と関係なく変わります。項目が増える、日付の形式が変わる、エラーの返し方が変わる。それでも手元のモックは昔のままなので、テストだけがいつまでも「昔の本物」を相手に緑を出し続けます。
この3つが重なると、「カバレッジは高いのに、本番でだけ落ちる」という状態ができあがります。逆に言えば、ズレる場所はだいたい決まっているということでもあります。だから、そこだけ見ればいい。
ひとこと補足:現場では「モック」「スタブ」「フェイク」がだいたい同じ意味で使われますが、厳密には、スタブ=決まった値を返すだけの代役、モック=どう呼ばれたか(回数・引数)まで確かめる代役、という違いがあります。この記事では両方まとめて「代役」として扱い、区別が効いてくる場面だけ言い分けます。
具体例——嘘をつく代役の、よくある形
現場で実際に困るのは、次のような代役です。どれも「AIが手を抜いた」わけではなく、そう作るなと言われていないから、そう作ったというだけの話です。
- いつも成功を返す:外部サービスは、落ちます。遅れます。混んでいると断ってきます。成功しか返さない代役でどれだけテストしても、失敗したときの動きは一行も確かめられていません。
- 応答の形が微妙に違う:項目名の綴り、大文字小文字、階層の深さ、日付の形式、数値が文字列で来るか。一文字の違いは、テストでは絶対に見つかりません(両側とも同じ思い込みで書かれているため)。
nullや空が来ることを考えていない:本物は、項目そのものが無い状態で返してくることがあります。代役が毎回きれいに値を詰めていると、その分岐は一度も通りません。- エラーの「返し方」が本物と違う:本物はステータスコードで異常を伝えてくるのに、代役は例外を投げる。逆もあります。受け取り方が違えば、こちらの処理は素通りします。
- 呼ばれ方を確かめていない:期待どおりの値が返ってきたことだけを見て、そもそも何回呼ばれたか・どんな引数で呼んだかを見ていない。リトライが二重に走っていても、テストは緑のままです。
- 代役を作りすぎて、確かめたい処理まで消えている:テスト対象のすぐ隣まで差し替えてしまい、実際に動いているのは代役だけ。これはAIのテストはカバレッジが高い|意味のあるテストとの差で書いた「通っているのに守れていない」の、いちばん出やすい形です。
- 時刻や乱数がそのまま:現在時刻や乱数を固定していないと、日付をまたいだ夜だけ落ちます。原因の切り分け方はたまに落ちるテスト(Flaky)の原因をAIに切り分けさせる手順へ。
並べてみると、ズレているものの多くが「失敗の側」「応答の形」「呼ばれ方」の3か所に集まっています。見る場所は、思ったより少ないのです。
影響——気づけるのが、いちばん遅いタイミングになる
代役の嘘は、その場では何も起こしません。困るのは、気づくのが最後になることです。
- 本番でしか出ない:手元でも、検証環境でも、CI(=変更のたびに自動でテストを回す仕組み)でも緑。本物と話すのが本番だけなら、ズレが表に出るのも本番だけです。
- 直したあとも緑のまま:原因を直しても、テストは前から緑なので「直った」という手応えが得られません。次に同じ場所が壊れても、やはり教えてくれません。
- 調べるのに時間がかかる:テストが通っている以上、まず疑うのは自分のコードです。代役のほうが間違っている可能性に行き着くまで、遠回りになりがちです。
- 同じ形の見落としがコピーされる:一度書いた代役は、次のテストでもコピーして使われます。思い込みは、静かに横へ広がります。
ここで言っておきたいのは、これは注意力が足りないから起きることではないということです。相手のサービスが変わったかどうかは、こちらからは見えません。返ってくる形の細部を全部覚えている人もいません。だから、個人の記憶ではなく手順で埋める——それが、この件でいちばん効く考え方です。
そしてもうひとつ。代役の作り方を一度そろえておくと、次のテストからはそれをまねするだけになります。今日30分かけて1本だけ整えておけば、半年後のあなたと、隣の席の人の分まで働いてくれます。
明日からやること(3ステップ)
新しい道具は要りません。この順番なら、今日触っているテスト1本から小さく始められます。
1. 本物の応答を1件だけ見せてから作らせる
いちばん効くのはここです。図の左です。AIに頼む前に、本物を一度だけ呼んで、返ってきたものをそのまま手元に取る。開発用の環境で構いません。すでにログに残っているなら、それを拾うだけでも十分です。
そのうえで、そのまま使える頼み方の例:
次の処理のテストで使う代役(モック/スタブ)を書いてください。応答の形は、下に貼った実物のとおりに再現してください。
1. 項目名・階層・型(数値か文字列か)・日付の形式を、実物から変えないでください。
2. 実物に無い項目を、気を利かせて足さないでください。
3. 実物から読み取れない部分(項目の意味・省略される条件など)は、推測で埋めず「確認が必要なこと」として別に並べてください。
対象の処理:(何を呼んで、返り値をどう使っているか)
実物の応答:(1件そのまま貼る。名前・メールなどは別の値に置き換えてから)
条件3がいちばん効きます。実物から分からないところを、AIは黙って埋めてしまうことがあります。この一文を入れておくと、「ここは確認してください」と返してくれるので、あなたが確認すべき点が先に見えます。もっともらしい埋め方の外し方はAIのハルシネーションの見抜き方|開発現場で気づく型も合わせてどうぞ。
貼る前のひと手間だけ、忘れずに。実物の応答には、氏名・メールアドレス・取引先名・トークンが入っていることがあります。そのまま貼らず、別の値に置き換えてから渡してください。どこまでなら渡してよいかの線引きは社内データをAIに渡す前の線引き|情報漏えいを防ぐ型に整理してあります。置き換える値づくりはAIにテストデータを作らせる|個人情報と偏りに気をつける型が使えます。
2. 成功だけでなく、失敗も作らせる
形が合ったら、次は落ちる側です。図の中央です。ここは「他のケースも書いて」と漠然と頼まない。返してほしい失敗を、こちらから名指しするほうがはるかに出ます。
さきほどの代役に、うまくいかないときの応答を追加してください。次のそれぞれについて、代役の設定を1つずつ用意してください。
1. 相手が異常を返してくる場合(本物と同じ返し方で。ステータスコードなのか例外なのかを実物に合わせる)
2. 応答は返るが中身が足りない場合(項目が無い、null、空の配列)
3. 時間がかかる/つながらない場合(タイムアウト、接続できない)
4. 混んでいて断られる場合(回数制限にかかったとき)
5. 形が想定と違う場合(数値のはずが文字列、日付の形式違い)
各ケースについて、こちらの処理がどう振る舞うべきかを1行で書き添えてください。この処理に当てはまらないケースは、無理に埋めないでください。
最後の一文を入れておくのが小さなコツです。これを言わないと、5つ全部を律儀に埋めようとして、起こりえないケースまで並びます。
そして、呼ばれ方の確認も1つだけ足しておくと安心です。「何回呼ばれたか」「どんな引数で呼んだか」。リトライを入れている処理なら、ここが二重送信の見張り役になります。失敗したときの戻し方そのものを設計する話はAI出力が不安定なときのフォールバック設計|リトライの型にまとめてあります。異常系の洗い出しを広げたいときは境界値・異常系をAIに考えさせて漏れを減らす手順へ。
3. 本物とズレたら気づく、細い1本を置く
最後は、代役が古くなったことに気づく仕組みです。図の右です。ここを置かないと、①と②の成果は少しずつ古びていきます。
大げさなものは要りません。本物を実際に1回だけ呼んで、応答の形が変わっていないかだけ見るテストを1本。中身の正しさまでは見なくて構いません。見るのはこれだけです。
- 期待している項目が、まだ全部あるか
- 型が変わっていないか(数値のはずが文字列になっていないか)
- 異常時の返し方が、まだ同じか
これを普段のテストとは分けて、1日1回・週1回など、頻度を落として回すのがおすすめです。毎回のCIに混ぜると、相手が一瞬不調なだけで赤くなり、そのうち誰も見なくなります。分けておけば、赤くなったときの意味がはっきりします——「本物が変わったかもしれない」。
余裕があれば、本物の応答を記録して、次からはそれを再生するやり方も検討の価値があります。多くの言語に、記録と再生を助ける仕組みがあります。記録したファイルを更新するだけで代役も一緒に新しくなるので、ズレが起きにくくなります。ただし記録の中に個人情報や認証情報がそのまま残りやすいので、保存する前に置き換える手順だけは決めておいてください。
結合まで含めて見たいときはE2E・結合テストのシナリオをAIに書かせる——観点の渡し方、既存のテストを壊さずに直したいときはAIに直させてもリグレッションを出さない既存テストの渡し方が近い話をしています。
モック・スタブのチェックリスト
全部に○が要るわけではありません。気になった行だけで十分です。
① AIに頼む前に
- 本物の応答を1件、実際に見たか(ログから拾うのでも可)
- 貼る前に、氏名・メール・トークンなどを別の値に置き換えたか
- 異常時に相手が何を返すか(ステータスコードか、例外か)を確かめたか
- 実物から読み取れない部分は「確認が必要」と分けて返すよう頼んだか
② 返ってきた代役を見るとき
- 項目名・階層・型・日付の形式が、実物と同じか
- 実物に無い項目が、気を利かせて足されていないか
- 失敗したときの応答が用意されているか(異常・空・遅い・断られる)
- エラーの返し方が、本物と同じ形か
- 何回呼ばれたか・どんな引数で呼んだかを確かめているか
- 確かめたい処理そのものまで、代役に差し替えられていないか
- 現在時刻・乱数が固定されているか
③ 置いたあとに
- 本物の形が変わったら気づける1本があるか
- その1本は、普段のテストと分けて回しているか
- 赤くなったとき、誰が見るかが決まっているか
- 記録・再生を使うなら、保存前に値を置き換える手順があるか
この記事のまとめ
AIは、代役を書き起こすのが速い。定型のコードを一から打つ重さを、まるごと引き受けてくれます。苦手なのは、あなたが相手にしている本物が、いまどんな顔をしているかを知ることです。だから、そこだけこちらから渡します。
やることは3つだけです。①本物の応答を1件見せてから作らせる/②失敗の側も名指しで作らせる/③ズレたら気づく細い1本を置く。この順番で組むと、テストは「通るための儀式」から、「壊れたときに教えてくれる仕組み」に近づきます。

もし今日、本番でだけ落ちる不具合を追いかけていたなら、その原因を「テストが甘かった」で片づけなくて大丈夫です。代役は、書いた時点の本物しか知りません。ズレるのは当たり前のことで、気づける場所を1か所つくれば、それでもう次からは早く分かります。今日は、いま開いているテスト1本の代役に、失敗の応答をひとつ足すところからで十分です。
よければ、こちらも
- テストそのものを疑う目を持ちたいときはAIが書いた単体テストを信用しすぎない|確認ポイント
- 通っているのに守れていない状態が気になるときはAIのテストはカバレッジが高い|意味のあるテストとの差
- 観点そのものを洗いたいときはAIにテストケースを洗い出させる|観点の与え方
- レビューで人が見るべき場所はAIにレビューさせてもバグが残る|人が見るべき観点