web-dev-qa-db-ja.com

分度器によるモックとスタブ

私はangularアプリを分度器でテストしたい。アプリにはサーバーと通信するAPIモジュールがある。これらのテスト中にこのApiモジュールをモックしたい。完全な統合はしたくないテスト、ただしAPIからの期待値を使用したユーザー入力からのテストこれにより、クライアントのテストを高速化できるだけでなく、接続エラーなどのEdgeケースをテストすることもできます。

分度器でこれを行うにはどうすればよいですか?統合テストのセットアップを始めました。

Npm分度器モジュールを使用し、Seleniumをインストールし、デフォルトの構成を調整し、 onProtractorRunner.js を使用して、セットアップが機能することを確認しました。

Ock笑の推奨される方法は何ですか?モックは、テストファイルで直接行うのではなく、ブラウザー内で行う必要があると思います。テストファイル内のコマンドは分度器固有のものであり、Seleniumランナーに送信されるものと想定しています。したがって、セッションおよびテスト中にJavaScriptオブジェクトを共有することはできません。

sinon.js のようなスパイライブラリが必要になると思われますか、これはすでに分度器に含まれていますか?

編集:分度器課題追跡システムのこの課題 を読んで、これを行う方法があります。基本的に、テストでモックモジュールを作成します。これは、ブラウザ/アプリケーションスコープで実行されるように送信されます。

編集:より有望な問題を以下に示します。最初の話は Angular App にモックを追加します。2番目の話は バックエンドのモック について話しています。

これは本当にすてきに見えます。この場合、Angularアプリは元の形式のままになります。しかし、現在これは非推奨のng-scenarioでのみ機能します。

30
user524824

このブログ投稿 Protractorの高度な使用シナリオについて説明しています。特に、分度器ブラウザオブジェクトのほとんど知られていないaddMockModule()メソッドをカバーしています。このメソッドを使用すると、Protractorでangularモジュール(つまり、APIモジュールのモックまたはスタブ)を作成し、ブラウザーにアップロードして、指定された仕様またはスペック。

9

分度器テスト内から$ httpBackend、コントローラー、またはサービスにアクセスできないため、別のangular=モジュールを作成し、テスト中にブラウザーに含めるという考えです。

  beforeEach(function(){
    var httpBackendMock = function() {
      angular.module('httpBackendMock', ['ngMockE2E', 'myApp'])
        .run(function($httpBackend) {
          $httpBackend.whenPOST('/api/packages').respond(200, {} );
        })
    }
    browser.addMockModule('httpBackendMock', httpBackendMock)
  })

ngMockE2Eを使用すると、アプリケーションの偽のバックエンド実装を作成できます。トピックに関する詳細な投稿があります http://product.moveline.com/testing-angular-apps-end-to-end-with-protractor.html

4
jvans

この時点では自分で試したことはありませんが、AngularはE2Eテスト用のモック$ httpBackendを提供します。

http://docs.angularjs.org/api/ngMockE2E/service/$httpBackend

したがって、上記のドキュメントページから、テストの前に次のようなものを使用できると思います

beforeEach(function() {
  $httpBackend.whenGET('/remote-url').respond(edgeCaseData);
});
2
Michal Charemza

成功とエラーのシナリオを処理できるように、少しカスタマイズ可能なモックモジュールを作成しました。おそらくモックの整理に役立ちます。

https://github.com/unDemian/protractor-mock

1
unDemian

私は分度器でいくつかのサービスをモックしようとしてきましたが、いくつかのブログを見て、自分に合ったソリューションにたどり着きました。アイデアは、重いモックを行うことではなく、いくつかのエラー応答を生成することです。フィクスチャについては、バックエンドにデータを入力するためにAPIサーバーにすでにバックドアがあります。

このソリューションでは、$provide.decorator()を使用して一部のメソッドを変更します。ここでのテストでの使用方法:

it('should mock a service', function () {
    app.mock.decorateService({
        // This will return a rejected promise when calling to "user"
        // service "login()" method resolved with the given object.
        // rejectPromise() is a convenience method
        user: app.mock.rejectPromise('login', { type: 'MockError' }),

        // You can decorate the service
        // Warning! This code get's stringified and send to the browser
        // it does not have access to node
        api: function ($delegate, $q) {
            $delegate.get = function () {
                var deferred = $q.defer();

                deferred.resolve({ id: 'whatever', name: 'tess' });

                return defer.promise;
            };

            return $delegate;
        },

        // Internally decorateService converts the function to string
        // so if you prefer you can set an string. Usefull for creating your
        // own helper methods like "rejectPromise()".
        dialog: [
            "function ($delegate, $window) {",
                "$delegate.alert = $window.alert;",
                "return $delegate;",
            "}"
        ].join('\n')
    });

    // ...

    // Important!
    app.mock.clearDecorators();
});

ここにコード:

App.prototype.mock = {
    // This must be called before ".get()"
    decorateService: function (services) {
        var code = [
            'var decorer = angular.module("serviceDecorator", ["visitaste"]);',
            'decorer.config(function ($provide) {'
        ];

        for (var service in services) {
            var fn = services[service];

            if (_.isFunction(fn)) {
                code.Push('$provide.decorator("'+ service +'", '+ String(fn) +');');
            } else if (_.isString(fn)) {
                code.Push('$provide.decorator("'+ service +'", '+ fn +');');
            }
        }

        code.Push('});');

        browser.addMockModule('serviceDecorator', code.join('\n'));
    },
    clearDecorators: function () {
        browser.clearMockModules();
    },
    rejectPromise: function (method, error, delay) {
        return [
            'function ($delegate, $q) {',
                '$delegate.'+ method +' = function () {',
                    'var deferred = $q.defer();',
                    '',
                    'setTimeout(function () {',
                        'deferred.reject('+ JSON.stringify(error) +');',
                    '}, '+ (delay || 200) +');',
                    '',
                    'return deferred.promise;',
                '};',
                '',
                'return $delegate;',
            '}'
        ].join('\n');
    }
};
1
doup

HTTPサーバーをスタブするためのいくつかのオプションを次に示します。

  • Stubby ノード、.Net、およびJavaをサポートする小さなWebサーバー。自分でインストールしてホストするために必要になります。
  • Apiary aホステッドサービス偽のAPIを作成します。これを使用して、APIドキュメントを作成することもできます。
0

分度器でエンドツーエンドのテストを実行するポイントは、アプリケーションが統合で機能することを検証することです。 UI要素を単独でテストしようとする場合、通常のテストから小さな要素を使用する方が簡単です。 AngularJS自体がディレクティブをテストするのとまったく同じです。

とはいえ、本当にモックしたい場合の1つの方法は、実際のサービスの代わりにスタブを使用して、アプリケーションの別個のビルドを作成することです。

0
iwein