6

ジャスミン単体テストで使用する名前、電子メールなどの単純な定数値を提供したいと思います。

同様の質問がここで尋ねられました: AngularJS + Karma: ディレクティブまたはコントローラーの単体テスト時にモック サービスを再利用する

C# では、モック データの小さな断片を保持する静的クラスを作成します。次のように、これらの値を単体テスト全体で使用できます。

static class SampleData
{
    public const string Guid = "0e3ae555-9fc7-4b89-9ea4-a8b63097c50a";
    public const string Password = "3Qr}b7_N$yZ6";

    public const string InvalidGuid = "[invalid-guid]";
    public const string InvalidPassword = "[invalid-password]"; 
}

Karma / Jasmine を使用して AngularJS アプリをテストするときに、同じ便利さを提供したいと考えています。

angular アプリに対してオブジェクトを定義できることはわかってconstantいます。次のように、実際のコードで使用する定数に対して既にこれを行っています。

myApp.constant('config', {apiUrl:'http://localhost:8082'})

このように別の定数を追加できますが、次のように、単体テストで使用するサンプル データ値のみを含みます。

myApp.constant('sampleData', {email: 'sample@email.com'}) 

次に、モック定数オブジェクトをテストに挿入するだけで、次のように実行できます

describe 'A sample unit test', ->
    beforeEach ->   module 'myApp'
    beforeEach inject ($injector) ->
        @sampleData = $injector.get 'sampleData'
        email = @sampleData.email
        # etc ...

しかし、これは私には少し怪しいようです。実稼働コードに、単体テストでのみ必要なサンプル データを含めたくありません。

angular / jasmine 単体テストに再利用可能なサンプル データ値をどのように便利に提供しますか?

ありがとう

4

1 に答える 1

10

これには 2 つの方法があります。

  • 関数呼び出しをスパイし、偽の値を返します。
  • モック クラス (および場合によってはそれらを初期化するためのモック データ) を作成し、必要な場所にロードします

最初のものは、いくつかの呼び出しを偽造するだけでよい場合に問題ありません。クラス全体でそれを行うことは持続不可能です。

たとえば、いくつかの特別な URL を作成するサービスがあるとします。メソッドの 1 つが absUrl に依存している場合、$locationオブジェクト内のメソッドをスパイすることで偽装できます。

describe('example') function () {
    beforeEach(inject(function () {
        spyOn($location, 'absUrl').andCallFake(function (p) {
            return 'http://localhost/app/index.html#/chickenurl';
        });
    }));
it('should return the url http://www.chicken.org') ... {
    // starting situation
    // run the function
    // asserts
}

ここSettingsで、サーバーへのリモート呼び出しを使用して初期化される、言語、テーマ、特別なパス、背景色、書体などのデータをカプセル化する Service があるとします。に依存するサービスをテストするのSettingsは苦痛です。毎回、spyOn で大きなコンポーネントをモックする必要があります。10個のサービスがある場合...それらすべてにspyOn関数をコピーペーストしたくありません。

ServiceA使用するSettingsサービス:

describe('ServiceA', function () {
var settings, serviceA;

beforeEach(module('myapp.mocks.settings'));  // mock settings
beforeEach(module('myapp.services.serviceA')); // load the service being tested

beforeEach(inject(function (_serviceA_, _settings_) {
    serviceA = _serviceA_;
    settings = _settings_;
}));

このテスト スイートのコンテナーでは、Settingsサービスへのすべての呼び出しがモックによって処理されます。このモックは、実際のインターフェイスと同じインターフェイスを持ちますが、ダミーの値を返します。このサービスはどこでもロードできることに注意してください。

(何らかの理由で実際の実装を使用する必要がある場合は、モックの前に実際の実装をロードし、その特定のケースで spyOn を使用して呼び出しを実際の実装に委譲することができます。)

通常、モック モジュールは app フォルダーの外に配置します。test単体テスト、e2e テストを含むフォルダーlibと、angular-mocks.js ファイルを含むフォルダーがあります。モックもそこに置きます。テストに必要なファイルを karma に伝えます。

    files: [
      'app/lib/jquery/jquery-1.9.1.js',
      'test/lib/jasmine-jquery.js',
      'app/lib/angular/angular.js',
      'app/lib/angular/angular-*.js',
      'test/lib/angular/angular-mocks.js',
      'test/lib/myapp/*.js', /* this is mine */
      'app/js/**/*.js',
      'test/unit/**/*.js'
    ],

このファイルtests/lib/myapp.mocks.settings.jsは、他のモジュールと同じように見えます。

(function () {
"use strict";

var m = angular.module('myapp.mocks.settings', []);

m.service('settings', function () { ... })
})

2 番目の問題 (オプション): ダミー値をすばやく変更したい。この例では、設定サービスは、初めてインスタンス化されるときにサーバーからオブジェクトを取得します。次に、サービスにはすべてのフィールドのゲッターがあります。これはサーバーへの一種のプロキシです。値が必要になるたびにリクエストを送信する代わりに、それらの束を取得してローカルに保存します。私のアプリケーションでは、実行時にサーバーの設定が変更されません。

何かのようなもの:

1. fetch http://example.org/api/settings
2. var localSettings = fetchedSettings;
3  getFieldA: function() { return localSettings.fieldA; }

グローバル名前空間を汚染します。settings.data.js次のような内容のファイルを作成しました。

var SETTINGS_RESPONSE = { fieldA: 42 };

モック サービスは、ファクトリでこのグローバル変数を使用してインスタンス化します。localSettings

于 2013-10-30T12:39:25.133 に答える