Aar*_*ius 84 angularjs karma-runner
我有一个使用Karma + Jasmine进行测试的AngularJS应用程序.我有一个我想要测试的函数,它接受一个大型JSON对象,将其转换为应用程序其余部分更易使用的格式,并返回该转换后的对象.而已.
对于我的测试,我希望你有单独的JSON文件(*.json)只有模拟JSON内容 - 没有脚本.对于测试,我希望能够加载JSON文件并将对象泵入我正在测试的函数中.
我知道我可以在这里描述的模拟工厂中嵌入JSON:http://dailyjs.com/2013/05/16/angularjs-5/但我真的希望JSON不包含在脚本中 - 只需直接JSON文件.
我尝试了一些东西,但我在这方面相当不错.首先,我设置我的Karma以包含我的JSON文件,看看它会做什么:
files = [
...
'mock-data/**/*.json'
...
]
Run Code Online (Sandbox Code Playgroud)
这导致:
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
Run Code Online (Sandbox Code Playgroud)
所以我把它改成只提供文件而不是"包含"它们:
files = [
...
{ pattern: 'mock-data/**/*.json', included: false }
...
]
Run Code Online (Sandbox Code Playgroud)
既然他们只是服务,我想我会尝试在我的规范中使用$ http加载文件:
$http('mock-data/two-metrics-with-anomalies.json')
Run Code Online (Sandbox Code Playgroud)
当我运行我收到的规范时:
Error: Unexpected request: GET mock-data/two-metrics-with-anomalies.json
Run Code Online (Sandbox Code Playgroud)
在我的理解中意味着它期望来自$ httpBackend的模拟响应.所以...在这一点上我不知道如何使用Angular实用程序加载文件,所以我想我会尝试jQuery,看看我是否至少可以让它工作:
$.getJSON('mock-data/two-metrics-with-anomalies.json').done(function(data) {
console.log(data);
}).fail(function(response) {
console.log(response);
});
Run Code Online (Sandbox Code Playgroud)
这导致:
Chrome 27.0 (Mac) LOG: { readyState: 4,
responseText: 'NOT FOUND',
status: 404,
statusText: 'Not Found' }
Run Code Online (Sandbox Code Playgroud)
我在查尔斯检查这个请求,它正在向我提出请求
/mock-data/two-metrics-with-anomalies.json
Run Code Online (Sandbox Code Playgroud)
而我已配置为由Karma"包含"的其余文件被请求,例如:
/base/src/app.js
Run Code Online (Sandbox Code Playgroud)
显然,Karma设置了某种基本目录来提供文件.所以对于踢,我改变了我的jquery数据请求
$.getJSON('base/mock-data/two-metrics-with-anomalies.json')...
Run Code Online (Sandbox Code Playgroud)
它的工作原理!但现在我觉得很脏,需要洗个澡.帮助我再次感觉清洁.
Cam*_*ron 81
我正在使用带角度种子的角度设置.我最终用直接的.json fixture文件和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}
],
Run Code Online (Sandbox Code Playgroud)
然后我的测试文件有:
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);
});
});
Run Code Online (Sandbox Code Playgroud)
真正的诀窍是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
Run Code Online (Sandbox Code Playgroud)
Piz*_*her 42
通过夹具提供JSON是最简单的,但由于我们的设置,我们不能轻易做到这一点,所以我写了一个替代的辅助函数:
$ bower install karma-read-json --save
OR
$ npm install karma-read-json --save-dev
OR
$ yarn add karma-read-json --dev
Run Code Online (Sandbox Code Playgroud)
将karma-read-json.js放入您的Karma文件中.例:
files = [
...
'bower_components/karma-read-json/karma-read-json.js',
...
]
Run Code Online (Sandbox Code Playgroud)确保您的JSON由Karma提供服务.例:
files = [
...
{pattern: 'json/**/*.json', included: false},
...
]
Run Code Online (Sandbox Code Playgroud)readJSON在测试中使用该功能.例:
var valid_respond = readJSON('json/foobar.json');
$httpBackend.whenGET(/.*/).respond(valid_respond);
Run Code Online (Sandbox Code Playgroud)TOB*_*der 10
我一直在努力寻找将外部数据加载到我的测试用例中的解决方案.以上链接: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'}
});
Run Code Online (Sandbox Code Playgroud)
然后在你的测试文件中:
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
....
}
Run Code Online (Sandbox Code Playgroud)
看起来你的解决方案是正确的,但有两件我不喜欢的事情:
我刚遇到这个问题并且必须迅速解决它,因为我没有时间离开截止日期,我做了以下事情
我的json资源很庞大,我无法将其粘贴到测试中,因此我必须将其保存为单独的文件 - 但我决定将其保留为javascript而不是json,然后我只是做了:
var someUniqueName = ... the json ...
我把这包括在业力包括..
如果需要,我仍然可以模拟后端的http响应.
$httpBackend.whenGET('/some/path').respond(someUniqueName);
我还可以编写一个新的角度模块来包含在这里,然后将json资源更改为类似的东西
angular.module('hugeJsonResource', []).constant('SomeUniqueName', ... the json ... );
然后简单地注入SomeUniqueName测试,看起来更干净.
甚至可能将它包装在服务中
angular.module('allTestResources',[]).service('AllTestResources', function AllTestResources( SomeUniqueName , SomeOtherUniqueName, ... ){
this.resource1 = SomeUniqueName;
this.resource2 = SomeOtherUniqueName;
})
Run Code Online (Sandbox Code Playgroud)
这个解决方案对我来说更快,同样干净,并且不需要任何新的学习曲线.所以我更喜欢这个.
| 归档时间: |
|
| 查看次数: |
67528 次 |
| 最近记录: |