ホームページ ウェブフロントエンド jsチュートリアル Jest の概要: 単体テスト、モック、および非同期コード

Jest の概要: 単体テスト、モック、および非同期コード

Nov 01, 2024 am 12:23 AM

Introduction to Jest: Unit Testing, Mocking, and Asynchronous Code

ジェストの紹介

Jest は JavaScript コードをテストするためのライブラリです。

これは Facebook によって管理されているオープンソース プロジェクトであり、React コードのテストに特に適していますが、これに限定されません。あらゆる JavaScript コードをテストできます。その強みは次のとおりです:

  • 速いです
  • スナップショットテストを実行できます
  • 独自の意見があり、選択を必要とせずにすぐに使えるすべての機能を提供します
export default function sum(a, n) {
  return a + b;
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

divide.test.js

import sum from './sum';

// Describe the test and wrap it in a function.
it('adds 1 + 2 to equal 3', () => {
  const result = sum(1, 2);

  // Jest uses matchers, like pretty much any other JavaScript testing framework.
  // They're designed to be easy to get at a glance;
  // here, you're expecting `result` to be 3.
  expect(result).toBe(3);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

マッチャー

マッチャーは、値をテストできるメソッドです。

  • toBe は === を使用して厳密な等価性を比較します。
  • toEqual は 2 つの変数の値を比較します。オブジェクトまたは配列の場合は、すべてのプロパティまたは要素が等しいかどうかをチェックします
  • null 値を渡す場合、toBeNull は true になります
  • 定義された値を渡す場合、toBeDefined は true になります (上記とは逆)
  • 未定義の値を渡す場合は toBeUnknown が true になります
  • toBeCloseTo は浮動小数点値を比較するために使用され、丸めエラーを回避します
  • toBeTruthy 値が true とみなされる場合は true (if と同様)
  • toBeFalsy 値が false とみなされる場合は true (if と同様)
  • Expect() の結果が引数
  • より大きい場合は toBeGreaterThan true
  • toBeGreaterThanOrEqual Expect() の結果が引数と等しいか、引数より大きい場合は true
  • Expect() の結果が引数
  • より小さい場合は toBeLessThan true
  • toBeLessThanOrEqual Expect() の結果が引数と等しいか、引数より小さい場合は true
  • toMatch は、正規表現パターン マッチングで文字列を比較するために使用されます
  • toContain は配列で使用されます。期待される配列の要素に引数が含まれている場合は true、set
  • toHaveLength(number): 配列の長さをチェックします
  • toHaveProperty(key, value): オブジェクトにプロパティがあるかどうかを確認し、オプションでその値を確認します
  • toThrow は、渡した関数が例外 (一般) または特定の例外をスローするかどうかをチェックします
  • toBeInstanceOf(): オブジェクトがクラスのインスタンスであるかどうかを確認します

依存関係

依存関係とは、アプリケーションが依存するコードの一部です。それはプロジェクト内の関数/オブジェクト、またはサードパーティの依存関係 (ex axios) である可能性があります

コードがないとアプリケーションが機能できない場合、そのコードは真の依存関係になります。

たとえば、電子メールを送信したり、API リクエストを行ったり、構成オブジェクトを構築したりする機能をアプリケーションに実装する場合

js プロジェクトのコードに依存関係を追加するには、2 つの方法があります。

輸入品

export default function sum(a, n) {
  return a + b;
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

依存関係の注入

単純な概念を表す単なる派手な用語です。

関数が外部依存関係からの機能を必要とする場合は、それを引数として挿入するだけです。

import sum from './sum';

// Describe the test and wrap it in a function.
it('adds 1 + 2 to equal 3', () => {
  const result = sum(1, 2);

  // Jest uses matchers, like pretty much any other JavaScript testing framework.
  // They're designed to be easy to get at a glance;
  // here, you're expecting `result` to be 3.
  expect(result).toBe(3);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

単体テスト

単体テストは、アプリケーションのセクション (「ユニット」と呼ばれる) が設計を満たし、意図したとおりに動作することを確認するために、ソフトウェア開発者によって作成および実行されます。

コードを分離してテストしたいので、依存関係の実際の実装は気にしません。
検証したい

  • コード単位が期待どおりに動作すること
  • 期待される結果を返します
  • 必要に応じてコラボレータ (依存関係) を呼び出します

そこで、依存関係を嘲笑することが重要になります。

嘲笑する

単体テストでは、モックは依存関係によって提供される機能をスタブ化する機能と、コードが依存関係とどのように相互作用するかを観察する手段を提供します。

モックは、依存関係をテストに直接組み込むのが高価であったり非現実的である場合、たとえば、コードが API への HTTP 呼び出しを行ったり、データベース層と対話したりする場合

などに特に役立ちます。

これらの依存関係に対する応答は、必要に応じて呼び出されるようにしながら、スタブアウトすることが望ましいです。ここでモックが役に立ちます。

モック関数を使用すると、次のことがわかります:
  • 受信した通話数
  • 各呼び出しで使用される Argument
  • の値。
  • 各呼び出しの 「コンテキスト」またはこの
  • 値。
  • 関数がどのように終了したか、およびどのような値が生成されたか

冗談で嘲笑する

モック関数を作成するにはいくつかの方法があります。
  • jest.fn メソッドを使用すると、新しいモック関数を直接作成できます。
  • オブジェクト メソッドをモックしている場合は、jest.spyOn を使用できます。
  • モジュール全体をモックしたい場合は、jest.mock を使用できます。

jest.fn メソッドは、それ自体が高階関数です。

これは、新しい未使用のモック関数を作成するファクトリ メソッドです。

JavaScript の関数は第一級市民であり、引数として渡すことができます。

各モック関数にはいくつかの特別なプロパティがあります。モック プロパティは基本です。このプロパティは、関数がどのように呼び出されたかに関するすべての疑似状態情報を含むオブジェクトです。このオブジェクトには 3 つの配列プロパティが含まれています:
  • 呼び出し [各呼び出しの引数]
  • インスタンス [各呼び出しの「この」値]
  • Results [関数が終了した値]、results プロパティには型 (return または throw) と値があります。
    • 関数は明示的に値を返します。
    • 関数は return ステートメントなしで完了まで実行されます (これは、未定義を返すのと同じです
    • 関数はエラーをスローします。
export default function sum(a, n) {
  return a + b;
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • https://codesandbox.io/s/implementing-mock-functions-tkc8b

モックベーシック

import sum from './sum';

// Describe the test and wrap it in a function.
it('adds 1 + 2 to equal 3', () => {
  const result = sum(1, 2);

  // Jest uses matchers, like pretty much any other JavaScript testing framework.
  // They're designed to be easy to get at a glance;
  // here, you're expecting `result` to be 3.
  expect(result).toBe(3);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

注入された依存関係をモックする

import { name, draw, reportArea, reportPerimeter } from './modules/square.js';
ログイン後にコピー
ログイン後にコピー

モジュールのモック化

jest.fn を使用して関数をモックする

// Constructor Injection

// DatabaseManager class takes a database connector as a dependency
class DatabaseManager {
    constructor(databaseConnector) {
        // Dependency injection of the database connector
        this.databaseConnector = databaseConnector;
    }

    updateRow(rowId, data) {
        // Use the injected database connector to perform the update
        this.databaseConnector.update(rowId, data);
    }
}

// parameter injection, takes a database connector instance in as an argument; easy to test!
function updateRow(rowId, data, databaseConnector) {
    databaseConnector.update(rowId, data);
}

ログイン後にコピー
ログイン後にコピー

このタイプのモックは、いくつかの理由からあまり一般的ではありません。

  • jest.mock はモジュール内のすべての関数に対してこれを自動的に実行します
  • jest.spyOn も同じことを行いますが、元の関数を復元できます

jest.mock でモジュールをモックする

より一般的なアプローチは、jest.mock を使用してモジュールのすべてのエクスポートをモック関数に自動的に設定することです

// 1. The mock function factory
function fn(impl = () => {}) {
  // 2. The mock function
  const mockFn = function(...args) {
    // 4. Store the arguments used
    mockFn.mock.calls.push(args);
    mockFn.mock.instances.push(this);
    try {
      const value = impl.apply(this, args); // call impl, passing the right this
      mockFn.mock.results.push({ type: 'return', value });
      return value; // return the value
    } catch (value) {
      mockFn.mock.results.push({ type: 'throw', value });
      throw value; // re-throw the error
    }
  }
  // 3. Mock state
  mockFn.mock = { calls: [], instances: [], results: [] };
  return mockFn;
}
ログイン後にコピー
ログイン後にコピー

jest.spyOn を使用して関数をスパイまたはモックする

メソッドが呼び出されるのを監視するだけで、元の実装は保持したい場合があります。また、実装をモックしたい場合もありますが、後でスイート内でオリジナルを復元します。

test("returns undefined by default", () => {
  const mock = jest.fn();

  let result = mock("foo");

  expect(result).toBeUndefined();
  expect(mock).toHaveBeenCalled();
  expect(mock).toHaveBeenCalledTimes(1);
  expect(mock).toHaveBeenCalledWith("foo");
});
ログイン後にコピー
ログイン後にコピー

元の実装を復元します

const doAdd = (a, b, callback) => {
  callback(a + b);
};

test("calls callback with arguments added", () => {
  const mockCallback = jest.fn();
  doAdd(1, 2, mockCallback);
  expect(mockCallback).toHaveBeenCalledWith(3);
});
ログイン後にコピー
ログイン後にコピー

JavaScript とイベント ループ

JavaScript はシングルスレッドです: 一度に実行できるタスクは 1 つだけです。通常、これは大したことではありませんが、30 秒かかるタスクを実行していると想像してください。そうです。そのタスク中は、何か他のことが起こるまで 30 秒待機します (JavaScript はデフォルトでブラウザのメイン スレッドで実行されます)。そのため、UI 全体が動かなくなってしまいます)。
2020 年、遅くて応答しない Web サイトを望んでいる人はいません。

幸いなことに、ブラウザは、JavaScript エンジン自体が提供していないいくつかの機能、Web API を提供します。これには、DOM APIsetTimeoutHTTP リクエスト などが含まれます。これは、非同期非ブロック動作
を作成するのに役立ちます。

export default function sum(a, n) {
  return a + b;
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • 呼び出しスタック - 関数を呼び出すと、関数は呼び出しスタックと呼ばれるものに追加されます。
  • WebAPI - setTimeout は WebAPI によって提供され、コールバック関数を受け取り、メインスレッドをブロックせずにタイマーを設定します
  • キュー - タイマーが終了すると、コールバックがキュー
  • に追加されます。
  • Event Loop - コールスタックが空かどうかを確認し、キュー内に実行するコールバックがあるかどうかを確認し、実行するコールスタックに移動します。
import sum from './sum';

// Describe the test and wrap it in a function.
it('adds 1 + 2 to equal 3', () => {
  const result = sum(1, 2);

  // Jest uses matchers, like pretty much any other JavaScript testing framework.
  // They're designed to be easy to get at a glance;
  // here, you're expecting `result` to be 3.
  expect(result).toBe(3);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

Jest を使用した非同期コードのテスト

Jest は通常、テストの関数を同期的に実行することを想定しています。

非同期操作を実行しても、テストが終了するまで待機する必要があることを Jest に知らせないと、誤検知が発生します。

import { name, draw, reportArea, reportPerimeter } from './modules/square.js';
ログイン後にコピー
ログイン後にコピー

非同期パターン
JavaScript で非同期操作を処理するには、いくつかのパターンがあります。最もよく使用されるものは次のとおりです:

  • コールバック
  • 約束と非同期/待機

コールバックのテスト

Jest はテストを実行しないため、コールバック内にテストを含めることはできません。テスト ファイルの実行は、コールバックが呼び出される前に終了します。これを修正するには、パラメータをテスト関数に渡します。これを完了と呼び出すと便利です。 Jest は、done() が呼び出されるまで待機してからテストを終了します。

// Constructor Injection

// DatabaseManager class takes a database connector as a dependency
class DatabaseManager {
    constructor(databaseConnector) {
        // Dependency injection of the database connector
        this.databaseConnector = databaseConnector;
    }

    updateRow(rowId, data) {
        // Use the injected database connector to perform the update
        this.databaseConnector.update(rowId, data);
    }
}

// parameter injection, takes a database connector instance in as an argument; easy to test!
function updateRow(rowId, data, databaseConnector) {
    databaseConnector.update(rowId, data);
}

ログイン後にコピー
ログイン後にコピー

約束

Promise を返す関数を使用して、テストから Promise を返します。

// 1. The mock function factory
function fn(impl = () => {}) {
  // 2. The mock function
  const mockFn = function(...args) {
    // 4. Store the arguments used
    mockFn.mock.calls.push(args);
    mockFn.mock.instances.push(this);
    try {
      const value = impl.apply(this, args); // call impl, passing the right this
      mockFn.mock.results.push({ type: 'return', value });
      return value; // return the value
    } catch (value) {
      mockFn.mock.results.push({ type: 'throw', value });
      throw value; // re-throw the error
    }
  }
  // 3. Mock state
  mockFn.mock = { calls: [], instances: [], results: [] };
  return mockFn;
}
ログイン後にコピー
ログイン後にコピー

非同期/待機

Promise を返す関数をテストするには、async/await を使用することもできます。これにより、構文が非常に単純かつ単純になります。

test("returns undefined by default", () => {
  const mock = jest.fn();

  let result = mock("foo");

  expect(result).toBeUndefined();
  expect(mock).toHaveBeenCalled();
  expect(mock).toHaveBeenCalledTimes(1);
  expect(mock).toHaveBeenCalledWith("foo");
});
ログイン後にコピー
ログイン後にコピー

ヒント

  • 関数が何を行うのか、何をテストしようとしているのかをよく理解する必要があります
  • テストしているコードの動作について考えてみましょう
  • 舞台を設定します:
    • 依存関係をモック/スパイします
    • コードはグローバル オブジェクトと対話していますか?私たちも彼らを嘲笑したりスパイしたりすることができます
    • テストは DOM と対話していますか?いくつかの偽の要素を構築して動作させることができます
    • テストを構造化する
    • 与えられた ...
    • 電話すると....
    • それでは...期待しています....
const doAdd = (a, b, callback) => {
  callback(a + b);
};

test("calls callback with arguments added", () => {
  const mockCallback = jest.fn();
  doAdd(1, 2, mockCallback);
  expect(mockCallback).toHaveBeenCalledWith(3);
});
ログイン後にコピー
ログイン後にコピー

リンク

  • https://medium.com/@rickhanlonii/ Understanding-jest-mocks-f0046c68e53c
  • https://jestjs.io/docs/en/mock-functions
  • https://codesandbox.io/s/implementing-mock-functions-tkc8b
  • https://github.com/BulbEnergy/jest-mock-examples
  • https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif
  • https://jestjs.io/docs/en/asynchronous
  • https://www.pluralsight.com/guides/test-asynchronous-code-jest

以上がJest の概要: 単体テスト、モック、および非同期コードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

javascriptの分解:それが何をするのか、なぜそれが重要なのか javascriptの分解:それが何をするのか、なぜそれが重要なのか Apr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

JavaScriptの進化:現在の傾向と将来の見通し JavaScriptの進化:現在の傾向と将来の見通し Apr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

JavaScriptエンジン:実装の比較 JavaScriptエンジン:実装の比較 Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

JavaScript:Web言語の汎用性の調査 JavaScript:Web言語の汎用性の調査 Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合) next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合) Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

C/CからJavaScriptへ:すべてがどのように機能するか C/CからJavaScriptへ:すべてがどのように機能するか Apr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合) next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合) Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

See all articles