У меня есть приложение 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. Итак ... на тот момент я не знал, как загрузить файл с помощью утилит 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
Судя по всему, Карма создает какой-то базовый каталог для хранения файлов. Поэтому для удовольствия я изменил свой запрос данных jquery на
$.getJSON('base/mock-data/two-metrics-with-anomalies.json')...
И это работает! Но теперь я чувствую себя грязным и мне нужно принять душ. Помоги мне снова почувствовать себя чистым.
источник
Обслуживать JSON через приспособление проще всего, но из-за нашей настройки мы не могли сделать это легко, поэтому я написал альтернативную вспомогательную функцию:
Репозиторий
Установить
$ bower install karma-read-json --save OR $ npm install karma-read-json --save-dev OR $ yarn add karma-read-json --dev
Применение
Поместите karma-read-json.js в свои файлы Karma. Пример:
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);
источник
npm install karma-read-json
вместоbower install karma-read-json
Я изо всех сил пытался найти решение для загрузки внешних данных в мои тестовые наборы. Ссылка выше: 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-ответом серверной части, если это необходимо.
$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 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
или какой-либо дополнительной конфигурации Karma, чтобы протестировать, например, службу Angular, используя$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(); }); });
источник