ホームページ >ウェブフロントエンド >jsチュートリアル >TDD 前: モック、スタブ、スパイとは何かを知る必要があるのはなぜですか?

TDD 前: モック、スタブ、スパイとは何かを知る必要があるのはなぜですか?

DDD
DDDオリジナル
2025-01-10 09:23:41175ブラウズ

Before TDD: Why you need to know what Mocks, Stubs, and Spies are?

皆さんこんにちは!今日は、非常に興味深いと思われるトピックを取り上げます。 TDD、BDD、テストの設計パターン、テストの書き方、その他多くの関連トピックについて論じた記事がオンラインに多数あることは知っています。しかし、テストの世界におけるより基本的な用語、つまり私たちが頻繁に使用する関数ですが、その意味や動作が必ずしも完全に理解されているとは限らないものについて説明している記事はほとんどありません。テストについて学び始めたばかりで、ライブラリ関数が何をするのか正確に理解していない場合は、この記事が役に立ちます。ぜひ読んでみてください!

モックとは何ですか?

テストを書き始めるとすぐに最初に遭遇するのはモックです。すでに使用しているけれども、その意味を正確に理解していない場合があります。それでは、詳しく見ていきましょう。

モックは主に単体テストで使用されます。これらは、通常は外部の依存関係から来るコンテンツ、オブジェクト、または応答をシミュレートするために使用されるツールであり、コンテンツに特定の情報が必要な場合に使用されます。

映画推薦システムをテストしていると想像してください。このシステムは、API から映画のリストを取得し、それを返します。

問題は、テストを実行するたびに実際の API が呼び出される場合、動作が遅くなり一貫性がなくなる可能性があり (ムービーが異なる可能性があるか、API がダウンしている可能性があります)、テストの信頼性が低下する可能性があります。

分かった、レオ、問題は分かった。でも、モックはこれをどうやって解決するの? そうですね、それは簡単です。API を呼び出す代わりに、その応答を映画の静的リストとして使用します。これは基本的に、映画のリストを使用して API 応答を「偽装」しています。

映画システムの例では、API を使用して映画を取得する fetchMoviesFromAPI() という関数をテストする場合、次のように API 応答をシミュレートするモックを作成できます。

// This is the mock
const MOVIES_FROM_API = [
    {
        id: 1,
        name: "Interstellar"
    },
    {
        id: 2,
        name: "Nosferatu"
    }
]

// Here, we’re telling fetchMoviesFromAPI to return our mock instead of calling the real API. This is a stub, which you’ll learn about in the next section.
const fetchMoviesFromAPI = jest.fn().mockResolvedValue(MOVIES_FROM_API)

;(async () => {
    {
        const expectedMovies = MOVIES_FROM_API
        const movies = await fetchMoviesFromAPI()

        expect(movies).toEqual(MOVIES_FROM_API)
    }
})()

モックを使用すると、テストは外部サービスに依存しないため、より効率的になります。さらに、リターンを完全に制御できるため、信頼性も高まり、潜在的な API の不安定性やダウンタイムを心配することなく、機能の検証に集中できるようになります。

モックは、テストに必要な呼び出しやその他のオブジェクトからの応答をシミュレートする静的オブジェクトです。

結局のところ、本物のガソリンを使わずに車をテストするようなものです。道路に出す前に、エンジンが確実に作動するように制御された環境を作成します。

モックを取得しましたが、スタブとは何ですか?

スタブもテスト ツールですが、目的は少し異なります。関数の動作をあらかじめ決められたものに置き換え、多くの場合モックを使用して特定の値を返します。

スタブは関数の動作を置き換えます。たとえば、その映画 API にアクセスすると、関数は実際の呼び出しを行わず、モック (映画の静的リスト) を参照します。

これらは、テストが外部サービスやインターネットに依存すべきではないことを思い出させるものでもあります。

少し背景を説明しましょう。オンライン購入の合計金額を計算するアプリケーションをテストしていると想像してください。計算には外部サービスから取得した料金が含まれます。テストを実行するたびに、この計算を行う必要があります。つまり、外部サービスを呼び出す必要があります。これにより、速度が遅く、不安定で、コストがかかり (外部サービスがリクエストごとに料金を請求する可能性があるため)、一貫性のないテスト (値が変更される可能性がある) が発生する可能性があります。

スタブを使用すると、実際のサービス呼び出しを固定の事前定義値 (はい、モック) に置き換えます。料金サービスを呼び出す代わりに、次のように言います。「常に料金として値 10 を返します。」

カートのアイテムの値を合計し、送料を追加する関数 CalculateTotalPurchase() をテストしたいと想像してください。スタブを使用して、配送料サービスを、配送料として常に「10」を返す値に置き換えます。このように:

// This is the mock
const MOVIES_FROM_API = [
    {
        id: 1,
        name: "Interstellar"
    },
    {
        id: 2,
        name: "Nosferatu"
    }
]

// Here, we’re telling fetchMoviesFromAPI to return our mock instead of calling the real API. This is a stub, which you’ll learn about in the next section.
const fetchMoviesFromAPI = jest.fn().mockResolvedValue(MOVIES_FROM_API)

;(async () => {
    {
        const expectedMovies = MOVIES_FROM_API
        const movies = await fetchMoviesFromAPI()

        expect(movies).toEqual(MOVIES_FROM_API)
    }
})()

これによりテストが簡素化され、再現性が確保され、常に同じように動作します。さらに、スタブはテストの分離に役立ち、有料 API の状態や可用性を心配する必要がなくなります。

要約すると、実際の牛乳の量を測るのではなく、常に牛乳 200ml と表示されている計量カップを使用してケーキのレシピをテストするようなものです。この方法では、牛乳が正しく計量されているかどうかを気にせずに、材料を混合できるかどうかだけをテストすることになります。

モック、スタブ...そして最後に、スパイとは何ですか?

オブジェクトをシミュレートするモックと、関数の動作を模倣するスタブを検討してきました。さて、スパイについて話しましょう。彼らは具体的に何をするのでしょうか?

スパイは関数を監視し、呼び出された回数、受け取ったパラメータ、および各実行の結果を記録します。これらを使用すると、関数の動作を変更せずに観察でき、すべてが期待どおりに動作していることを確認できます。

プロジェクトの通知モジュールをテストしていると想像してください。注文が完了するたびに、システムは顧客にメッセージを送信し、エントリを記録する必要があります。この場合、これらのアクションが確実に実行されるようにするだけで、いずれも置き換えたくありません。スパイを使用すると、これらの機能の動作を変更することなく監視できます。これにより、以下を確認できるようになります。

  • 関数が呼び出された場合
  • 何回呼び出されました
  • 受け取った引数

たとえば、顧客に通知を送信し、エントリを記録する completeOrder() 関数をスパイでテストしたい場合は、次のように検証できます。

  • 通知関数が呼び出された場合
  • ログ関数が呼び出された場合
  • これらの関数が受け取った引数。
// This is the mock
const MOVIES_FROM_API = [
    {
        id: 1,
        name: "Interstellar"
    },
    {
        id: 2,
        name: "Nosferatu"
    }
]

// Here, we’re telling fetchMoviesFromAPI to return our mock instead of calling the real API. This is a stub, which you’ll learn about in the next section.
const fetchMoviesFromAPI = jest.fn().mockResolvedValue(MOVIES_FROM_API)

;(async () => {
    {
        const expectedMovies = MOVIES_FROM_API
        const movies = await fetchMoviesFromAPI()

        expect(movies).toEqual(MOVIES_FROM_API)
    }
})()

結論としては、シェフがキッチンで何をしているかを観察するためにカメラを設置するようなものです。彼らがやっていることをあなたは邪魔しません。レシピに従っているかどうかを確認するだけです。

それで、以上です!信頼性が高く効率的なテストを作成するための基本要素であるモック、スタブ、スパイという用語を学び、理解しました。これで、学習をさらに深めることができます。また会いましょう、さようなら!

以上がTDD 前: モック、スタブ、スパイとは何かを知る必要があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:ネットパック次の記事:ネットパック