在Karma + AngularJStesting中加载一个模拟的JSON文件

我有一个AngularJS应用程序设置与testing使用Karma +茉莉花。 我有一个函数,我想testing一个大型的JSON对象,将其转换为应用程序其余部分更易于使用的格式,然后返回转换后的对象。 而已。

对于我的testing,我想你有单独的JSON文件(* .json)与模拟JSON内容只 – 没有脚本。 对于testing,我希望能够加载JSON文件,并将对象泵入我testing的函数中。

我知道我可以在模拟工厂内embeddedJSON,如下所示: http : //dailyjs.com/2013/05/16/angularjs-5/但我真的希望JSON不要包含在脚本中 – 只要直接JSON文件。

我已经尝试了一些东西,但我在这个领域相当不错。 首先,我将Karma设置为包含我的JSON文件,以查看它将执行的操作:

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,看看我是否至less可以得到这个工作:

 $.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 

而我已经configuration为由Karma“包含”的其余文件正在被请求,例如:

 /base/src/app.js 

显然,Karma设置了某种基本目录来提供文件。 所以踢我改变了我的jquery数据请求

 $.getJSON('base/mock-data/two-metrics-with-anomalies.json')... 

它的工作原理! 但现在我觉得很肮脏,需要洗澡。 帮助我再次感觉干净。

我正在使用angular种子的angular度设置。 我最终解决了这个问题,直接.JSON夹具文件和jasmine-jquery.js。 其他人暗示了这个答案,但是花了我一点时间才把所有的东西都放在正确的位置。 我希望这可以帮助别人。

我有我的JSON文件在文件夹/test/mock和我的Web /app/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} ], 

那么我的testing文件有:

 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 

用法

  1. 把karma-read-json.js放到你的Karma文件中。 例:

     files = [ ... 'bower_components/karma-read-json/karma-read-json.js', ... ] 
  2. 确保你的JSON由Karma服务。 例:

     files = [ ... {pattern: 'json/**/*.json', included: false}, ... ] 
  3. 在testing中使用readJSON函数。 例:

     var valid_respond = readJSON('json/foobar.json'); $httpBackend.whenGET(/.*/).respond(valid_respond); 

我一直在努力寻找一种解决scheme来将外部数据加载到我的testing用例中。 上面的链接: 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'} }); 

然后在你的testing文件中:

 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 .... } 

看起来像你的解决scheme是正确的,但有两件事我不喜欢它:

  • 它使用茉莉花
  • 它需要新的学习曲线

我只是遇到了这个问题,不得不迅速解决,因为我没有时间离开截止date,我做了以下

我的JSON资源是巨大的,我不能复制粘贴到testing,所以我不得不把它一个单独的文件 – 但我决定把它保持为JavaScript而不是JSON,然后我只是做了:

var someUniqueName = ... the json ...

我把这包括在业力conf包括..

如果需要的话,我仍然可以嘲笑一个后端http响应。

$httpBackend.whenGET('/some/path').respond(someUniqueName);

我也可以写一个新的angular度模块包含在这里,然后将json资源改为类似的东西

angular.module('hugeJsonResource', []).constant('SomeUniqueName', ... the json ... );

然后简单地将SomeUniqueName注入testing,看起来更干净。

也许甚至包装在一个服务

 angular.module('allTestResources',[]).service('AllTestResources', function AllTestResources( SomeUniqueName , SomeOtherUniqueName, ... ){ this.resource1 = SomeUniqueName; this.resource2 = SomeOtherUniqueName; }) 

这个解决scheme对我来说更快,就像干净,而且不需要任何新的学习曲线。 所以我更喜欢这一个。

我正在寻找同样的事情。 我会尝试这种方法 。 它使用configuration文件来包含模拟数据文件,但是这些文件比json多一点,因为json需要传递给angular.module('MockDataModule').value,然后你的unit testing也可以加载多个模块然后可以将该值设置为注入beforeEach注入调用。

还发现另一种看起来很有前途的xhr请求,并不昂贵,这是一个很好的post,描述中途testing,如果我明白权利让你的控制器/服务实际上检索数据,如在e2etesting,但你的中途testing有实际访问控制器范围(e2e我不觉得)。

您可以使用karma-html2js预处理器来获取添加到__html__ global的json文件。

看到这个答案的细节: https : //stackoverflow.com/a/22103160/439021

有Karma预处理器也可以使用JSON文件。 这里有一个:

https://www.npmjs.org/package/karma-ng-json2js-preprocessor

和无耻的插件,这是我开发的,有RequireJS支持

https://www.npmjs.org/package/karma-ng-json2js-preprocessor-requirejs

这里是Cameron的答案的替代scheme,不需要jasmine-jquery或任何额外的Karmaconfiguration来testing例如使用$resource的Angular服务:

 angular.module('myApp').factory('MyService', function ($resource) { var Service = $resource('/:user/resultset'); return { getResultSet: function (user) { return Service.get({user: user}).$promise; } }; }); 

和相应的unit testing:

 describe('MyServiceTest', function(){ var $httpBackend, MyService, testResultSet, otherTestData ; beforeEach(function (done) { module('myApp'); inject(function ($injector) { $httpBackend = $injector.get('$httpBackend'); MyService = $injector.get('MyService'); }); // Loading fixtures $.when( $.getJSON('base/test/mock/test_resultset.json', function (data) { testResultSet = data; }), $.getJSON('base/test/mock/test_other_data.json', function (data) { otherTestData = data; }) ).then(done); }); it('should have some resultset', function() { $httpBackend.expectGET('/blahblahurl/resultset').respond(testResultSet); MyService.getResultSet('blahblahurl').then(function (resultSet) { expect(resultSet.length).toBe(59); }); $httpBackend.flush(); }); });