Karma + Jasmineを使用したテストで設定されたAngularJSアプリがあります。大きなJSONオブジェクトを受け取り、それをアプリの他の部分でより使いやすい形式に変換し、変換したオブジェクトを返す関数をテストする必要があります。それでおしまい。
私のテストでは、模擬JSONコンテンツのみを備えた個別のJSONファイル(* .json)が必要です。スクリプトは不要です。テストのために、JSONファイルをロードし、テストしている関数にオブジェクトをポンプで送りたいと思います。
ここで説明されているように、モックファクトリ内にJSONを埋め込むことができることを知っています: http://dailyjs.com/2013/05/16/angularjs-5/ スクリプト内-単純なJSONファイル。
私はいくつかのことを試しましたが、私はこの分野でかなり初心者です。最初に、JSONファイルを含めるようにKarmaをセットアップして、それがどうなるかを確認します。
files = [
...
'mock-data/**/*.json'
...
]
その結果:
Chrome 27.0 (Mac) ERROR
Uncaught SyntaxError: Unexpected token :
at /Users/aaron/p4workspace4/depot/sitecatalyst/branches/anomaly_detection/client/anomaly-detection/mock-data/two-metrics-with-anomalies.json:2
そこで、ファイルを「含める」のではなく、単にファイルを提供するように変更しました。
files = [
...
{ pattern: 'mock-data/**/*.json', included: false }
...
]
それらが提供されるだけなので、仕様内から$ httpを使用してファイルをロードしようと思いました:
$http('mock-data/two-metrics-with-anomalies.json')
受け取った仕様を実行したとき:
Error: Unexpected request: GET mock-data/two-metrics-with-anomalies.json
私の理解では、これは$ httpBackendからの模擬応答を期待していることを意味します。だから...この時点でAngularユーティリティを使用してファイルをロードする方法がわからなかったので、少なくともそれを動作させることができるかどうかjQueryを試してみようと思いました:
$.getJSON('mock-data/two-metrics-with-anomalies.json').done(function(data) {
console.log(data);
}).fail(function(response) {
console.log(response);
});
これは次の結果になります。
Chrome 27.0 (Mac) LOG: { readyState: 4,
responseText: 'NOT FOUND',
status: 404,
statusText: 'Not Found' }
チャールズでこのリクエストを検査し、次のリクエストを行っています
/mock-data/two-metrics-with-anomalies.json
Karmaによって「含まれる」ように設定した残りのファイルは、たとえば次の場所で要求されています。
/base/src/app.js
どうやらKarmaがファイルを提供する何らかのベースディレクトリを設定しているようです。キックのために、jquery data requestを
$.getJSON('base/mock-data/two-metrics-with-anomalies.json')...
そしてそれは動作します!しかし、今私は汚いと感じ、シャワーを浴びる必要があります。再び清潔に感じてください。
angularシードを使用したangularセットアップを使用しています。私はこれをストレート.jsonフィクスチャファイルとjasmine-jquery.jsで解決しました。他の人はこの答えをほのめかしましたが、すべてのピースを正しい場所に収めるのに時間がかかりました。これが他の人の助けになることを願っています。
Jsonファイルは/test/mock
フォルダーにあり、webappは/app
にあります。
私のkarma.conf.js
には次のエントリがあります(他のものもあります):
basePath: '../',
files: [
...
'test/vendor/jasmine-jquery.js',
'test/unit/**/*.js',
// fixtures
{pattern: 'test/mock/*.json', watched: true, served: true, included: false}
],
私のテストファイルには次のものがあります:
describe('JobsCtrl', function(){
var $httpBackend, createController, scope;
beforeEach(inject(function ($injector, $rootScope, $controller) {
$httpBackend = $injector.get('$httpBackend');
jasmine.getJSONFixtures().fixturesPath='base/test/mock';
$httpBackend.whenGET('http://blahblahurl/resultset/').respond(
getJSONFixture('test_resultset_list.json')
);
scope = $rootScope.$new();
$controller('JobsCtrl', {'$scope': scope});
}));
it('should have some resultsets', function() {
$httpBackend.flush();
expect(scope.result_sets.length).toBe(59);
});
});
本当のトリックはjasmine.getJSONFixtures().fixturesPath='base/test/mock';
で、もともとtest/mock
に設定しただけでしたが、そこにbase
が必要でした。ベースなしでは、次のようなエラーが発生しました。
Error: JSONFixture could not be loaded: /test/mock/test_resultset_list.json (status: error, message: undefined)
at /Users/camd/gitspace/treeherder-ui/webapp/test/vendor/jasmine-jquery.js:295
フィクスチャを介してJSONを提供するのが最も簡単ですが、セットアップのために簡単に行うことができなかったため、代替ヘルパー関数を作成しました。
$ bower install karma-read-json --save
OR
$ npm install karma-read-json --save-dev
OR
$ yarn add karma-read-json --dev
Karmaファイルにkarma-read-json.jsを入れます。例:
files = [
...
'bower_components/karma-read-json/karma-read-json.js',
...
]
JSONがKarmaによって提供されていることを確認してください。例:
files = [
...
{pattern: 'json/**/*.json', included: false},
...
]
テストでreadJSON
関数を使用します。例:
var valid_respond = readJSON('json/foobar.json');
$httpBackend.whenGET(/.*/).respond(valid_respond);
外部データをテストケースにロードするソリューションを見つけるのに苦労していました。上記のリンク: http://dailyjs.com/2013/05/16/angularjs-5/ 私のために働いた。
いくつかのメモ:
「defaultJSON」をモックデータファイルのキーとして使用する必要があります。これは、defaultJSONを参照するだけでよいため、問題ありません。
mockedDashboardJSON.js:
'use strict'
angular.module('mockedDashboardJSON',[])
.value('defaultJSON',{
fakeData1:{'really':'fake2'},
fakeData2:{'history':'faked'}
});
次に、テストファイルで:
beforeEach(module('yourApp','mockedDashboardJSON'));
var YourControlNameCtrl, scope, $httpBackend, mockedDashboardJSON;
beforeEach(function(_$httpBackend_,defaultJSON){
$httpBackend.when('GET','yourAPI/call/here').respond(defaultJSON.fakeData1);
//Your controller setup
....
});
it('should test my fake stuff',function(){
$httpBackend.flush();
//your test expectation stuff here
....
}
あなたのソリューションは正しいもののように見えますが、私がそれについて好きではない2つのことがあります:
私はこの問題に出くわし、締め切りに間に合う時間がなかったのですぐに解決しなければなりませんでした。
私のjsonリソースは巨大であり、テストにコピーアンドペーストすることができなかったため、別のファイルを保持する必要がありましたが、jsonではなくjavascriptとして保持することを決定し、それから単純に実行しました:
var someUniqueName = ... the json ...
そして、私はこれをkarma conf includes。に含めました。
必要に応じて、バックエンドHTTP応答をモックできます。
$httpBackend.whenGET('/some/path').respond(someUniqueName);
ここに含める新しいangularモジュールを作成してから、jsonリソースを次のように変更することもできます。
angular.module('hugeJsonResource', []).constant('SomeUniqueName', ... the json ... );
そして、SomeUniqueName
をテストに挿入するだけです。
おそらくサービスでそれを包む
angular.module('allTestResources',[]).service('AllTestResources', function AllTestResources( SomeUniqueName , SomeOtherUniqueName, ... ){
this.resource1 = SomeUniqueName;
this.resource2 = SomeOtherUniqueName;
})
このソリューションは、私にとっては高速で、同じようにクリーンで、新しい学習曲線を必要としませんでした。だから私はこれを好む。
私は同じものを探していました。 このアプローチ を試します。構成ファイルを使用してモックデータファイルを含めますが、ファイルはjsonよりも少し大きくなります。これは、jsonをangular.module( 'MockDataModule')。valueに渡す必要があり、ユニットテストで複数のモジュールを読み込むこともできるためです。そして、値セットはbeforeEachインジェクトコールにインジェクトするために利用可能です。
また、 別のアプローチ 費用のかからないxhrリクエストに対して有望に見えますが、中間テストを説明する素晴らしい投稿です。これを理解すれば、コントローラー/サービスが実際にe2eテストのようにデータを取得できます、しかし、あなたの中間テストはコントローラーのスコープに実際にアクセスできます(e2eはそうは思いません)。
JSONファイルでも動作するKarmaプリプロセッサがあります。ここにあります:
https://www.npmjs.org/package/karma-ng-json2js-preprocessor
そして恥知らずなプラグイン、これは私が開発したもので、RequireJSをサポートしています
https://www.npmjs.org/package/karma-ng-json2js-preprocessor-requirejs
karma-html2js-preprocessor を使用して、__ html__グローバルに追加されたjsonファイルを取得できます。
詳細については、この回答を参照してください: https://stackoverflow.com/a/22103160/439021