Загрузка макетного файла JSON в тесте Karma+AngularJS
у меня есть приложение AngularJS, настроенное с помощью тестов с использованием Karma+Jasmine. У меня есть функция, которую я хочу проверить, которая принимает большой объект JSON, преобразует его в формат, который более потребляемый остальной частью приложения, и возвращает этот преобразованный объект. Вот и все.
для моих тестов я бы хотел, чтобы у вас были отдельные файлы JSON (*.json) только с макетом содержимого JSON-нет сценария. Для теста я хотел бы иметь возможность загрузить файл JSON и перекачать объект в функцию, которую я тестирование.
Я знаю, что могу встроить JSON в макет фабрики, как описано здесь:http://dailyjs.com/2013/05/16/angularjs-5/ но я действительно хочу, чтобы JSON не содержался в скрипте-просто прямые файлы JSON.
я пробовал несколько вещей, но я достаточно нуб в этой области. Во-первых, я настроил свою карму, чтобы включить мой файл 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. So...at в этот момент я не знал, как загрузить файл с помощью угловых утилит, поэтому я подумал, что попробую 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' }
я проверяю этот запрос в Charles, а он делает запрос
/mock-data/two-metrics-with-anomalies.json
в то время как остальные файлы, которые я настроил для "включения" кармой, запрашиваются, например:
/base/src/app.js
по-видимому, карма создает какой-то базовый каталог для обслуживания файлов. Поэтому для пинков я изменил свой запрос данных jquery на
$.getJSON('base/mock-data/two-metrics-with-anomalies.json')...
и это работает! Но теперь я чувствую себя грязным и нужно принять душ. Помоги мне снова почувствовать себя чистым.
8 ответов:
Я использую угловую установку с угловым семенем. Я закончил тем, что решил это с помощью straight .файлы приспособлений json и jasmine-jquery.js. Другие ссылались на этот ответ, но мне потребовалось некоторое время, чтобы собрать все части в нужном месте. Я надеюсь, что это поможет кому-то еще.
у меня есть мои файлы json в папке
/test/mock
и мой веб-приложение находится в/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
использование
поставить кармы-читать в формате JSON.js в ваших карма-файлах. Пример:
files = [ ... 'bower_components/karma-read-json/karma-read-json.js', ... ]
убедитесь, что ваш JSON обслуживается кармой. Пример:
files = [ ... {pattern: 'json/**/*.json', included: false}, ... ]
использовать
Я изо всех сил пытался найти решение для загрузки внешних данных в моих тестовых случаев. Ссылка выше: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 был огромен, и я не мог скопировать его в тест, поэтому мне пришлось сохранить его в отдельном файле - но я решил сохранить его как javascript, а не json, и тогда я просто сделал:
var someUniqueName = ... the json ...
и я включил это в karma conf включает..
Я все еще могу издеваться над ответом http backend, если это необходимо.
$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; })
это решение было быстрее для меня, так же чисто, и не требовало какой-либо новой кривой обучения. так что я предпочитаю этот.
Я искал то же самое. Я собираюсь попробовать этот подход. Он использует файлы конфигурации для включения файлов макетных данных, но файлы немного больше, чем json, потому что json должен быть передан в angular.модуль('MockDataModule').значение, а затем ваши модульные тесты также могут загружать несколько модулей,а затем набор значений доступен для ввода в вызов beforeeach inject.
также нашел другой подход это выглядит многообещающим для запросы xhr, которые не являются дорогостоящими, это отличный пост, который описывает тестирование на полпути, которое, если я правильно понимаю, позволяет вашему контроллеру/службе фактически получать данные, как в тесте e2e, но ваш тест на полпути имеет фактический доступ к области контроллера (e2e не думаю).
есть препроцессоры Karma, которые также работают с файлами JSON. Здесь есть один:
https://www.npmjs.org/package/karma-ng-json2js-preprocessor
и бесстыдный плагин, это тот, который я разработал, который имеет поддержку RequireJS
https://www.npmjs.org/package/karma-ng-json2js-preprocessor-requirejs
можно использовать karma-html2js-препроцессор чтобы получить файлы json, добавленные в__ html _ _ global.
смотрите этот ответ для деталей:https://stackoverflow.com/a/22103160/439021
вот альтернатива Камерон ответ, без необходимости
jasmine-jquery
ни какой-либо дополнительной конфигурации кармы, чтобы проверить, например, угловой сервис с помощью$resource
:angular.module('myApp').factory('MyService', function ($resource) { var Service = $resource('/:user/resultset'); return { getResultSet: function (user) { return Service.get({user: user}).$promise; } }; });
и соответствующий модульный тест:
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(); }); });