ホームページ > ウェブフロントエンド > jsチュートリアル > AngularJSテストのモッキング依存関係

AngularJSテストのモッキング依存関係

Jennifer Aniston
リリース: 2025-02-20 12:28:16
オリジナル
360 人が閲覧しました

Mocking Dependencies in AngularJS Tests

コアポイント

  • Angularjsはテストを念頭に置いて生まれ、その組み込み依存性噴射メカニズムにより、各コンポーネントをJavaScriptテストフレームワーク(Jasmineなど)を使用してテストできます。
  • 単体テストの模擬には、テストコードスニペットを分離する機能が含まれます。これは、依存関係が異なるソースから来るため、困難な場合があります。 AngularJSのシミュレーションは、一般的に使用されるAngularJSサービスのセットのシミュレーションを提供するangular-mocksモジュールで簡素化されます。
  • AngularJのサービスシミュレーションは、実際のサービスのインスタンスを取得してサービスを聴くことで、または
  • を使用してシミュレーションサービスを実装することで実現できます。後者の方法が望ましいので、サービスの実際のメソッド実装を呼び出すことを避けることができます。 $provide AngularJのプロバイダーシミュレーションは、サービスシミュレーションと同様のルールに従います。
  • メソッドは、テストで実装する必要があります。テストファイルで
  • 関数で定義されている関数が不要な場合、空の関数に値を割り当てることができます。 $get グローバルオブジェクト(サードパーティライブラリによって作成されたグローバルな「ウィンドウ」オブジェクトまたはオブジェクトの一部など)は、それらを$getに注入するか、グローバルオブジェクトを使用して値または定数を作成して注入することでシミュレートできます。必要に応じて。
  • $windowAngularjs設計コンセプトにはテストが含まれています。フレームワークのソースコードは非常によくテストされており、フレームワークを使用して記述されたコードもテスト可能です。組み込みの依存関係注入メカニズムにより、AngularJSで記述されたすべてのコンポーネントをテストすることができます。 AngularJSアプリケーションのコードは、既存のJavaScriptテストフレームワークを使用してユニットテストできます。 AngularJSコードのテストに使用される最も一般的なフレームワークはジャスミンです。この記事のすべてのサンプルコードスニペットは、Jasmineを使用して書かれています。 Angularプロジェクトで他のテストフレームワークを使用する場合でも、この記事で説明したアイデアを適用できます。
この記事では、angularjsコードの単位テストとテストの経験がすでにあることを前提としています。テストの専門家である必要はありません。テストの基本的な理解があり、AngularJSアプリケーションの簡単なテストケースを書くことができる場合は、この記事を読み続けることができます。

単体テストにおけるシミュレーションの役割

各ユニットテストのタスクは、コードの機能を単独でテストすることです。依存関係が異なるソースから来る可能性があり、シミュレートされるオブジェクトの責任を完全に理解する必要があるため、テスト中のシステムを分離することは困難な場合があります。 JavaScriptなどの標準的に入力されていない言語では、シミュレーションがシミュレートされるオブジェクトの構造を理解するのが容易ではないため、シミュレーションは困難です。同時に、柔軟性、つまり、テスト中のシステムが現在使用しているオブジェクトの一部のみをシミュレートし、残りを無視する柔軟性も提供します。

angularjsテストのock

AngularJSの主な目標の1つはテスト可能性であるため、コアチームはテストを容易にするためにこれに特別な努力を注いでおり、angular-mocksモジュールでの一連のシミュレーションを提供します。このモジュールには、AngularJSアプリケーションで広く使用されている一連のAngularJSサービス($http$timeout$animateなど)をめぐるシミュレーションが含まれています。このモジュールは、開発者がテストを作成するのにかかる時間を短縮します。

これらのシミュレーションは、実際のビジネスアプリケーションのテストを作成するときに非常に役立ちます。同時に、アプリケーション全体をテストするには十分ではありません。フレームワーク内の依存関係を模倣する必要がありますが、モックされたものではありません - サードパーティのプラグイン、グローバルオブジェクト、またはアプリケーションで作成された依存関係から依存関係があります。この記事では、Angularjsの依存関係を模倣に関するいくつかのヒントを紹介します。

シミュレーションサービス

サービスは、AngularJSアプリケーションで最も一般的な依存関係タイプです。おそらくすでにご存知のように、サービスはAngularjsの過負荷用語です。サービス、工場、価値、定数、またはプロバイダーを指す場合があります。次のセクションでプロバイダーについて説明します。サービスは、次の方法のいずれかでシミュレートできます。

インジェクションブロックを使用して実際のサービスのインスタンスを取得し、サービスを聞くための方法。
  • を使用してシミュレーションサービスを実装します。
  • $provide
  • 最初の方法は、呼び出しサービスの実際のメソッド実装につながる可能性があるため、最初の方法が好きではありません。 2番目の方法を使用して、次のサービスをシミュレートします。

次のコードスニペットにより、上記のサービスのシミュレーションが作成されます。

angular.module('sampleServices', [])
  .service('util', function() {
    this.isNumber = function(num) {
      return !isNaN(num);
    };

    this.isDate = function(date) {
      return (date instanceof Date);
    };
  });
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
上記の例ではジャスミンを使用してスパイを作成しますが、Sinon.jsに置き換えて同等の機能を実現できます。

テストに必要なすべてのモジュールをロードした後、すべてのシミュレーションを作成することをお勧めします。それ以外の場合、サービスがロードされたモジュールで定義されている場合、実際の実装はシミュレートされた実装をオーバーライドします。
module(function($provide) {
  $provide.service('util', function() {
    this.isNumber = jasmine.createSpy('isNumber').andCallFake(function(num) {
      // 模拟实现
    });
    this.isDate = jasmine.createSpy('isDate').andCallFake(function(num) {
      // 模拟实现
    });
  });
});

// 获取模拟服务的引用
var mockUtilSvc;

inject(function(util) {
  mockUtilSvc = util;
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

定数、工場、および値は、

を使用して個別にシミュレートできます。

$provide.constantシミュレーションプロバイダー$provide.factory $provide.valueシミュレーションプロバイダーは、シミュレーションサービスに似ています。執筆プロバイダーをock笑するときにも従う必要があるすべてのルールは従わなければなりません。次のプロバイダーを検討してください

次のコードスニペットは、上記のプロバイダーのシミュレーションを作成します。

プロバイダーと他のシングルトンへの参照を取得することの違いは、プロバイダーがこの時点で工場に変換されるため、この時点でプロバイダーが

ブロックで利用できないことです。
angular.module('mockingProviders',[])
  .provider('sample', function() {
    var registeredVals = [];

    this.register = function(val) {
      registeredVals.push(val);      
    };

    this.$get = function() {
      function getRegisteredVals() {
        return registeredVals;
      }

      return {
        getRegisteredVals: getRegisteredVals
      };
    };
  });
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ブロックを使用してオブジェクトを取得できます。

プロバイダーを定義する場合、
module(function($provide) {
  $provide.provider('sample', function() {
    this.register = jasmine.createSpy('register');

    this.$get = function() {
      var getRegisteredVals = jasmine.createSpy('getRegisteredVals');

      return {
        getRegisteredVals: getRegisteredVals
      };
    };
  });
});

// 获取提供程序的引用
var sampleProviderObj;

module(function(sampleProvider) {
  sampleProviderObj = sampleProvider;
});
ログイン後にコピー
ログイン後にコピー
メソッドもテストに実装する必要があります。テストファイルの関数で定義されている関数が必要ない場合は、空の関数に割り当てることができます。

アナログモジュール

テストファイルにロードされるモジュールに他の多くのモジュールが必要な場合、必要なすべてのモジュールがロードされない限り、テスト中のモジュールをロードできません。これらのすべてのモジュールをロードすると、テストからいくつかの実際のサービス方法が呼び出される可能性があるため、テストが失敗することがあります。これらの困難を回避するために、仮想モジュールを作成して測定されたモジュールをロードできます。

たとえば、

次のコードが、追加のサービスを追加したモジュールを表しているとします。

angular.module('sampleServices', [])
  .service('util', function() {
    this.isNumber = function(num) {
      return !isNaN(num);
    };

    this.isDate = function(date) {
      return (date instanceof Date);
    };
  });
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
次のコードは、サンプルサービスのテストファイルの

ブロックです。 beforeEach

または、上記の仮想モジュールにサービスのシミュレートされた実装を追加することができます。
module(function($provide) {
  $provide.service('util', function() {
    this.isNumber = jasmine.createSpy('isNumber').andCallFake(function(num) {
      // 模拟实现
    });
    this.isDate = jasmine.createSpy('isDate').andCallFake(function(num) {
      // 模拟实现
    });
  });
});

// 获取模拟服务的引用
var mockUtilSvc;

inject(function(util) {
  mockUtilSvc = util;
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

約束に戻る方法をシミュレート

エンドツーエンドの角度アプリケーションを書くことは、約束を使用せずに難しい場合があります。約束を返す方法に依存するコードのスニペットをテストすることが課題になります。通常のジャスミンスパイは、テスト中の関数が実際の約束構造を持つオブジェクトを予想するため、いくつかのテストケースを失敗させます。

非同期方法は、静的値で約束を返す別の非同期方法を使用してシミュレートできます。次の工場を検討してください

上記の工場で

関数をテストします。ご覧のとおり、それは
angular.module('mockingProviders',[])
  .provider('sample', function() {
    var registeredVals = [];

    this.register = function(val) {
      registeredVals.push(val);      
    };

    this.$get = function() {
      function getRegisteredVals() {
        return registeredVals;
      }

      return {
        getRegisteredVals: getRegisteredVals
      };
    };
  });
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

にサービスを提供する方法に依存しています。 getData()メソッドの機能をテストする前に、サービスと方法をシミュレートする必要があります。 dataSourceSvc getAllItems()getData()サービスには、静的値を使用して約束を解決または拒否することを可能にする

および

メソッドがあります。これらの方法は、約束を返すモッキング方法のテストに非常に役立ちます。次のコードスニペットは、$qファクトリ:when()をシミュレートします reject() dataSourceSvc

約束は、次のダイジェストサイクルの後に操作を完了します。ダイジェストサイクルは、実際のアプリケーションでは継続的に実行されますが、テストでは継続的に実行されません。したがって、約束を実施するには、手動で
module(function($provide) {
  $provide.provider('sample', function() {
    this.register = jasmine.createSpy('register');

    this.$get = function() {
      var getRegisteredVals = jasmine.createSpy('getRegisteredVals');

      return {
        getRegisteredVals: getRegisteredVals
      };
    };
  });
});

// 获取提供程序的引用
var sampleProviderObj;

module(function(sampleProvider) {
  sampleProviderObj = sampleProvider;
});
ログイン後にコピー
ログイン後にコピー
に電話する必要があります。次のコードスニペットには、サンプルテストが表示されます

$qグローバルオブジェクトをシミュレート$rootScope.$digest()

グローバルオブジェクトは、次のソースから来ています
angular.module('first', ['second', 'third'])
  // util 和 storage 分别在 second 和 third 中定义
  .service('sampleSvc', function(utilSvc, storageSvc) {
    // 服务实现
  });
ログイン後にコピー
グローバルな「ウィンドウ」オブジェクトの一部である

オブジェクト(たとえば、LocalStorage、IndexEdDB、Mathなど)。

JQuery、Underscore、Moment、Breeze、またはその他のライブラリなどのサードパーティライブラリによって作成されたオブジェクト。

    デフォルトでは、グローバルオブジェクトをシミュレートできません。それらをシミュレート可能にするために、特定の手順に従う必要があります。
  1. 操作はビジネスロジックを実行せず、UIを操作し、データソースと通信しないため、数学オブジェクトまたはユーティリティオブジェクト(アンダースコアライブラリによって作成された)をシミュレートしたくない場合があります。ただし、$ .AJAX、LocalStorage、WebSocket、Breeze、Toastなどのオブジェクトをシミュレートする必要があります。これらのオブジェクトが模擬されていない場合、単体テストを実行するときに実際の操作を実行するため、不要なUIの更新、ネットワーク呼び出し、およびテストコードのエラーにつながる可能性があります。
  2. 依存関係の注入により、Angularで記述されたコードのすべての部分がテスト可能です。 DIを使用すると、実際のオブジェクトシムに従うオブジェクトを渡すことができます。これにより、テストされたコードが実行されたときに壊れないようにします。グローバルオブジェクトを注入できれば、シミュレートできます。グローバルオブジェクトを注入可能にする方法は2つあります。

    グローバルオブジェクトを必要とするサービス/コントローラーに
      >
    1. を注入し、グローバルオブジェクトにアクセスして$windowにアクセスします。たとえば、次のサービスでは$window$windowを介してLocalStorageを使用しています。
    angular.module('sampleServices', [])
      .service('util', function() {
        this.isNumber = function(num) {
          return !isNaN(num);
        };
    
        this.isDate = function(date) {
          return (date instanceof Date);
        };
      });
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
      グローバルオブジェクトを使用して値または定数を作成し、必要な場合に注入します。たとえば、次のコードはastrの定数です。
    1. 定数を構成ブロックまたはプロバイダーに注入することができ、定数を装飾できないため、
    グローバルオブジェクトを値ではなく定数でラップすることを好みます。
    module(function($provide) {
      $provide.service('util', function() {
        this.isNumber = jasmine.createSpy('isNumber').andCallFake(function(num) {
          // 模拟实现
        });
        this.isDate = jasmine.createSpy('isDate').andCallFake(function(num) {
          // 模拟实现
        });
      });
    });
    
    // 获取模拟服务的引用
    var mockUtilSvc;
    
    inject(function(util) {
      mockUtilSvc = util;
    });
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    次のコードスニペットには、ローカルストレージとtoAstrのシミュレーションが表示されます。

    結論
    angular.module('mockingProviders',[])
      .provider('sample', function() {
        var registeredVals = [];
    
        this.register = function(val) {
          registeredVals.push(val);      
        };
    
        this.$get = function() {
          function getRegisteredVals() {
            return registeredVals;
          }
    
          return {
            getRegisteredVals: getRegisteredVals
          };
        };
      });
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    模擬は、あらゆる言語で単体テストを書くことの重要なコンポーネントの1つです。これまで見てきたように、依存関係の注入は、テストとシミュレーションにおいて重要な役割を果たします。コードは、その機能を簡単にテストできるように、方法で整理する必要があります。この記事では、AngularJSアプリケーションをテストするときにシミュレートする最も一般的なオブジェクトのセットをリストします。この記事に関連するコードは、GitHubからダウンロードできます。 AngularJSテスト(FAQ)

    のモッキング依存関係に関する

    FAQ AngularJSテストで依存関係をock笑する目的は何ですか? AngularJSテストのモッキング依存関係は、単体テストの重要な部分です。開発者は、テストされたコードを分離し、依存関係の動作をシミュレートできます。このようにして、実際にコードを呼び出すことなく、コードが依存関係とどのように対話するかをテストできます。これは、依存関係が複雑で、遅い、またはテスト中に避けたい副作用がある場合に特に役立ちます。これらの依存関係をock笑することにより、制御された環境でコードの機能をテストすることに焦点を当てることができます。

    Angularjsで模擬サービスを作成する方法は?

    AngularJSで模擬サービスを作成するには、モジュール構成で

    サービスを使用することが含まれます。

    サービスの

    、または$provideメソッドを使用して、サービスのシミュレートされた実装を定義できます。基本的な例は次のとおりです $provide この例では、valueメソッドを使用して、シミュレートされた実装の実装を定義します。テスト中、この模擬サービスは実際のサービスの代わりに使用されます。 factory service(スペースの制限のために、FAQの残りの質問を1つずつ尋ねてください。簡潔で明確な答えを提供するために最善を尽くします。)

    以上がAngularJSテストのモッキング依存関係の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート