私はangularアプリを分度器でテストしたい。アプリにはサーバーと通信するAPIモジュールがある。これらのテスト中にこのApiモジュールをモックしたい。完全な統合はしたくないテスト、ただしAPIからの期待値を使用したユーザー入力からのテストこれにより、クライアントのテストを高速化できるだけでなく、接続エラーなどのEdgeケースをテストすることもできます。
分度器でこれを行うにはどうすればよいですか?統合テストのセットアップを始めました。
Npm分度器モジュールを使用し、Seleniumをインストールし、デフォルトの構成を調整し、 onProtractorRunner.js を使用して、セットアップが機能することを確認しました。
Ock笑の推奨される方法は何ですか?モックは、テストファイルで直接行うのではなく、ブラウザー内で行う必要があると思います。テストファイル内のコマンドは分度器固有のものであり、Seleniumランナーに送信されるものと想定しています。したがって、セッションおよびテスト中にJavaScriptオブジェクトを共有することはできません。
sinon.js のようなスパイライブラリが必要になると思われますか、これはすでに分度器に含まれていますか?
編集:分度器課題追跡システムのこの課題 を読んで、これを行う方法があります。基本的に、テストでモックモジュールを作成します。これは、ブラウザ/アプリケーションスコープで実行されるように送信されます。
編集:より有望な問題を以下に示します。最初の話は Angular App にモックを追加します。2番目の話は バックエンドのモック について話しています。
これは本当にすてきに見えます。この場合、Angularアプリは元の形式のままになります。しかし、現在これは非推奨のng-scenarioでのみ機能します。
このブログ投稿 Protractorの高度な使用シナリオについて説明しています。特に、分度器ブラウザオブジェクトのほとんど知られていないaddMockModule()
メソッドをカバーしています。このメソッドを使用すると、Protractorでangularモジュール(つまり、APIモジュールのモックまたはスタブ)を作成し、ブラウザーにアップロードして、指定された仕様またはスペック。
分度器テスト内から$ 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
この時点では自分で試したことはありませんが、AngularはE2Eテスト用のモック$ httpBackendを提供します。
http://docs.angularjs.org/api/ngMockE2E/service/$httpBackend
したがって、上記のドキュメントページから、テストの前に次のようなものを使用できると思います
beforeEach(function() {
$httpBackend.whenGET('/remote-url').respond(edgeCaseData);
});
成功とエラーのシナリオを処理できるように、少しカスタマイズ可能なモックモジュールを作成しました。おそらくモックの整理に役立ちます。
私は分度器でいくつかのサービスをモックしようとしてきましたが、いくつかのブログを見て、自分に合ったソリューションにたどり着きました。アイデアは、重いモックを行うことではなく、いくつかのエラー応答を生成することです。フィクスチャについては、バックエンドにデータを入力するために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');
}
};
分度器でエンドツーエンドのテストを実行するポイントは、アプリケーションが統合で機能することを検証することです。 UI要素を単独でテストしようとする場合、通常のテストから小さな要素を使用する方が簡単です。 AngularJS自体がディレクティブをテストするのとまったく同じです。
とはいえ、本当にモックしたい場合の1つの方法は、実際のサービスの代わりにスタブを使用して、アプリケーションの別個のビルドを作成することです。