Mam skonfigurowaną aplikację AngularJS z testami przy użyciu Karma + Jasmine. Mam funkcję, którą chcę przetestować, która pobiera duży obiekt JSON, konwertuje go na format, który jest bardziej użyteczny przez resztę aplikacji, i zwraca przekonwertowany obiekt. Otóż to.
Do moich testów chciałbym mieć osobne pliki JSON (* .json) tylko z fałszywą zawartością JSON - bez skryptu. Na potrzeby testu chciałbym móc załadować plik JSON i wpompować obiekt do testowanej funkcji.
Wiem, że mogę osadzić JSON w fałszywej fabryce, jak opisano tutaj: http://dailyjs.com/2013/05/16/angularjs-5/ ale naprawdę chcę, aby JSON nie był zawarty w skrypcie - po prostu zwykły JSON akta.
Próbowałem kilku rzeczy, ale w tej dziedzinie jestem dość noobem. Najpierw skonfigurowałem Karmę tak, aby zawierała mój plik JSON, aby zobaczyć, co zrobi:
files = [
...
'mock-data/**/*.json'
...
]
Spowodowało to:
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
Więc zmieniłem to tak, aby tylko obsługiwał pliki, a nie je „włączał”:
files = [
...
{ pattern: 'mock-data/**/*.json', included: false }
...
]
Teraz, gdy są tylko obsługiwane, pomyślałem, że spróbuję załadować plik przy użyciu $ http z mojej specyfikacji:
$http('mock-data/two-metrics-with-anomalies.json')
Kiedy uruchomiłem specyfikację, którą otrzymałem:
Error: Unexpected request: GET mock-data/two-metrics-with-anomalies.json
Co w moim rozumieniu oznacza, że oczekuje fałszywej odpowiedzi od $ httpBackend. Więc ... w tym momencie nie wiedziałem, jak załadować plik za pomocą narzędzi Angular, więc pomyślałem, że spróbuję wypróbować jQuery, aby sprawdzić, czy przynajmniej uda mi się to uruchomić:
$.getJSON('mock-data/two-metrics-with-anomalies.json').done(function(data) {
console.log(data);
}).fail(function(response) {
console.log(response);
});
To skutkuje:
Chrome 27.0 (Mac) LOG: { readyState: 4,
responseText: 'NOT FOUND',
status: 404,
statusText: 'Not Found' }
Sprawdzam tę prośbę w Charles i zwraca się do
/mock-data/two-metrics-with-anomalies.json
Podczas gdy pozostałe pliki, które skonfigurowałem jako „dołączane” przez Karmę, są żądane pod adresem, na przykład:
/base/src/app.js
Najwyraźniej Karma tworzy jakiś katalog bazowy, z którego będą obsługiwane pliki. Więc dla kopnięć zmieniłem żądanie danych jQuery na
$.getJSON('base/mock-data/two-metrics-with-anomalies.json')...
I to działa! Ale teraz czuję się brudna i muszę wziąć prysznic. Pomóż mi znów poczuć się czystym.
źródło
Udostępnianie JSON przez urządzenie jest najłatwiejsze, ale z powodu naszej konfiguracji nie mogliśmy tego łatwo zrobić, więc napisałem alternatywną funkcję pomocniczą:
Magazyn
zainstalować
$ bower install karma-read-json --save OR $ npm install karma-read-json --save-dev OR $ yarn add karma-read-json --dev
Stosowanie
Umieść karma-read-json.js w swoich plikach Karma. Przykład:
files = [ ... 'bower_components/karma-read-json/karma-read-json.js', ... ]
Upewnij się, że Twój JSON jest obsługiwany przez Karmę. Przykład:
files = [ ... {pattern: 'json/**/*.json', included: false}, ... ]
Użyj tej
readJSON
funkcji w swoich testach. Przykład:var valid_respond = readJSON('json/foobar.json'); $httpBackend.whenGET(/.*/).respond(valid_respond);
źródło
npm install karma-read-json
zamiastbower install karma-read-json
Starałem się znaleźć rozwiązanie do ładowania danych zewnętrznych do moich przypadków testowych. Powyższy link: http://dailyjs.com/2013/05/16/angularjs-5/ Pracował dla mnie.
Kilka uwag:
"defaultJSON" musi być użyty jako klucz w twoim fałszywym pliku danych, to jest w porządku, ponieważ możesz po prostu odwołać się do defaultJSON.
mockedDashboardJSON.js:
'use strict' angular.module('mockedDashboardJSON',[]) .value('defaultJSON',{ fakeData1:{'really':'fake2'}, fakeData2:{'history':'faked'} });
Następnie w pliku testowym:
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 .... }
źródło
wygląda na to, że Twoje rozwiązanie jest właściwe, ale są dwie rzeczy, których w nim nie lubię:
właśnie natknąłem się na ten problem i musiałem go szybko rozwiązać, ponieważ nie miałem czasu na ostateczny termin, i zrobiłem następujące
mój zasób json był ogromny i nie mogłem go skopiować i wkleić go do testu, więc musiałem zachować osobny plik - ale zdecydowałem się zachować go jako javascript zamiast json, a potem po prostu zrobiłem:
var someUniqueName = ... the json ...
i włączyłem to do karmy conf obejmuje.
W razie potrzeby nadal mogę mockować odpowiedź http zaplecza.
$httpBackend.whenGET('/some/path').respond(someUniqueName);
Mógłbym również napisać nowy moduł kątowy, który zostanie dołączony tutaj, a następnie zmienić zasób json na coś podobnego
angular.module('hugeJsonResource', []).constant('SomeUniqueName', ... the json ... );
a następnie po prostu wstrzyknij
SomeUniqueName
do testu, który wygląda czyściej.może nawet zapakuj go w usługę
angular.module('allTestResources',[]).service('AllTestResources', function AllTestResources( SomeUniqueName , SomeOtherUniqueName, ... ){ this.resource1 = SomeUniqueName; this.resource2 = SomeOtherUniqueName; })
to rozwiązanie było dla mnie szybsze, tak samo czyste i nie wymagało nowej krzywej uczenia się. więc wolę ten.
źródło
Szukałem tego samego. Spróbuję tego podejścia . Używa plików konfiguracyjnych, aby dołączyć pozorowane pliki danych, ale pliki są nieco większe niż json, ponieważ json musi zostać przekazany do angular.module ('MockDataModule'). Value, a następnie testy jednostkowe mogą również ładować wiele modułów a następnie ustawiona wartość jest dostępna do wstrzyknięcia do wywołania wstrzyknięcia beforeEach.
Znalazłem również inne podejście, które wygląda obiecująco w przypadku żądań xhr, które nie są kosztowne, to świetny post opisujący testy w połowie drogi, które, jeśli dobrze rozumiem, pozwalają kontrolerowi / usłudze faktycznie pobierać dane, jak w teście e2e, ale twój test w połowie ma rzeczywiste dostęp do zakresu kontrolera (e2e chyba nie).
źródło
Istnieją preprocesory Karma, które również współpracują z plikami JSON. Jest jeden tutaj:
https://www.npmjs.org/package/karma-ng-json2js-preprocessor
I bezwstydna wtyczka, to jest ta, którą opracowałem, która ma wsparcie dla RequireJS
https://www.npmjs.org/package/karma-ng-json2js-preprocessor-requirejs
źródło
Możesz użyć preprocesora karma-html2js-preprocesor, aby pobrać pliki json dodane do globalnego __html__.
zobacz tę odpowiedź, aby uzyskać szczegółowe informacje: https://stackoverflow.com/a/22103160/439021
źródło
Oto alternatywa dla odpowiedzi Camerona , bez potrzeby
jasmine-jquery
ani dodatkowej konfiguracji Karmy, aby przetestować np. Usługę Angular przy użyciu$resource
:angular.module('myApp').factory('MyService', function ($resource) { var Service = $resource('/:user/resultset'); return { getResultSet: function (user) { return Service.get({user: user}).$promise; } }; });
I odpowiedni test jednostkowy:
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(); }); });
źródło