कर्म + AngularJS परीक्षण के भीतर एक नकली JSON फ़ाइल लोड हो रही है


85

मेरे पास कर्म + जैस्मीन का उपयोग करके परीक्षणों के साथ एक AngularJS ऐप है। मेरे पास एक फ़ंक्शन है जो मैं परीक्षण करना चाहता हूं जो एक बड़ी 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 से नकली प्रतिक्रिया की उम्मीद करता है। इसलिए ... इस बिंदु पर मुझे पता नहीं था कि कोणीय उपयोगिताओं का उपयोग करके फ़ाइल को कैसे लोड किया जाए, इसलिए मैंने सोचा कि मैं 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

जबकि कर्मा द्वारा मेरे द्वारा शामिल की जाने वाली बाकी फाइलें उदाहरण के लिए अनुरोध की जा रही हैं:

/base/src/app.js

जाहिर तौर पर कर्मा ने फाइलों को सेवा देने के लिए किसी प्रकार की आधार निर्देशिका की स्थापना की। तो किक के लिए मैंने अपने jquery डेटा अनुरोध को बदल दिया

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

और यह काम करता है! लेकिन अब मुझे गंदा लग रहा है और शॉवर लेने की जरूरत है। मुझे फिर से साफ महसूस करने में मदद करें।

जवाबों:


82

मैं कोणीय बीज के साथ कोणीय सेटअप का उपयोग कर रहा हूं। मैंने इसे सीधे .json स्थिरता फ़ाइलों और चमेली- 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

1
हाय कैमरून, मुझे एक त्रुटि मिल रही है: TypeError: Object # <Object> का कोई तरीका 'getJSONFixtures' नहीं है ... चमेली में बदलाव किया गया है या कुछ और?
मेलबर्न

7
एहसास नहीं हुआ कि मुझे चमेली-जेकरी की आवश्यकता है ... इसे स्थापित किया और त्रुटि गायब हो गई
मेलबर्न

यह दृष्टिकोण काफी क्रियात्मक और जटिल लगता है ... मुझे नहीं पता कि ये "जुड़नार" अतिरिक्त लाभ प्रदान करते हैं, लेकिन यदि आप चाहते हैं तो नीचे दिया गया दृष्टिकोण समय-समय पर JSON फाइल पढ़ना है।
सेप्टाग्राम

43

स्थिरता के माध्यम से JSON की सेवा करना सबसे आसान है लेकिन हमारे सेटअप के कारण हम ऐसा आसानी से नहीं कर सकते हैं इसलिए मैंने एक वैकल्पिक सहायक फ़ंक्शन लिखा है:

कोष

इंस्टॉल

$ bower install karma-read-json --save

  OR

$ npm install karma-read-json --save-dev

  OR

$ yarn add karma-read-json --dev

प्रयोग

  1. अपनी कर्म फाइलों में कर्म-वाचन-json.js लगाएं। उदाहरण:

    files = [
      ...
      'bower_components/karma-read-json/karma-read-json.js',
      ...
    ]
    
  2. सुनिश्चित करें कि आपके JSON को कर्म द्वारा परोसा जा रहा है। उदाहरण:

    files = [
      ...
      {pattern: 'json/**/*.json', included: false},
      ...
    ]
    
  3. readJSONअपने परीक्षणों में फ़ंक्शन का उपयोग करें । उदाहरण:

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

1
यदि आप बोवर का उपयोग करने या स्थापित करने में असमर्थ हैं, तो चमेली-जैक्सन एक बढ़िया विकल्प है, जिसके लिए चमेली-जेकरी की आवश्यकता होती है। (बिग-कॉर्प पॉलिसी, मेरे मामले में।) मैंने अभी npm ( npmjs.com/package/karma-read-json ) के माध्यम से इंस्टॉल किया है और इसने बहुत अच्छा काम किया है।
मेलिसा एवरी-वियर

2
मुझे लगता है कि यह सबसे अच्छा तरीका है क्योंकि इसके लिए बोवर पर निर्भरता की आवश्यकता नहीं है ... बस कर्म / चमेली और कर्म-रीड-जेन। मैं भी npm install karma-read-jsonइसके बजाय चलने में सक्षम थाbower install karma-read-json
एरिक फुलर

कर्म दृष्टिकोण के लिए शानदार प्रतिक्रिया - स्पष्ट विवरण के लिए धन्यवाद!
खानाबदोश

ए) इस मंच के लिए थोड़े नया है, बी) एक कोणीय मॉड्यूल बनाने की कोशिश कर रहे jquery का उपयोग नहीं कर रहा है। इसने मेरे लिए अच्छा काम किया। मेरे सेट-अप ने कर्म पर घुटा हुआ है ।config.json -> फाइलें [] .. मैंने कर्म में कुछ नहीं जोड़ा ।config.json ।। "जहां संपत्ति संपत्ति का मानक स्थान है।
टेरीरी

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'}
});

फिर अपनी परीक्षण फ़ाइल में:

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

मुझे संदेह है .. क्या प्रति जोंस फ़ाइल में एक मॉड्यूल होगा? क्योंकि मैंने एकल मूल्यों पर एक से अधिक मूल्यों को जोड़ने का प्रयास किया, मुझे दूसरे प्रदाता के लिए अज्ञात प्रदाता त्रुटि मिल रही है
पवन

6

ऐसा लगता है कि आपका समाधान सही है, लेकिन 2 चीजें हैं जो मुझे पसंद नहीं हैं:

  • यह चमेली का उपयोग करता है
  • इसके लिए नए सीखने की अवस्था की आवश्यकता होती है

मैं बस इस समस्या में भाग गया और इसे जल्दी से हल करना था क्योंकि मेरे पास समय सीमा के लिए कोई समय नहीं बचा था, और मैंने निम्नलिखित किया

मेरा json संसाधन बहुत बड़ा था, और मैं इसे परीक्षण में पेस्ट नहीं कर सका, इसलिए मुझे इसे एक अलग फाइल रखनी पड़ी - लेकिन मैंने इसे 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; 
})

यह समाधान मेरे लिए तेज़ था, बिल्कुल स्वच्छ और किसी भी नए सीखने की अवस्था की आवश्यकता नहीं थी। इसलिए मैं इसे पसंद करता हूं।


4

मैं उसी चीज की तलाश में था। मैं इस दृष्टिकोण की कोशिश करने जा रहा हूं । यह मॉक डेटा फ़ाइलों को शामिल करने के लिए कॉन्फ़िगरेशन फ़ाइलों का उपयोग करता है, लेकिन फाइलें json की तुलना में थोड़ी अधिक होती हैं, क्योंकि json को angular.module ('MockDataModule') में पारित करने की आवश्यकता होती है। मान और फिर आपकी इकाई परीक्षण कई मॉड्यूल भी लोड कर सकते हैं। और फिर मान सेट पहले उपलब्ध इंजेक्शन कॉल में इंजेक्ट होने के लिए उपलब्ध है।

एक अन्य दृष्टिकोण भी पाया जो कि xhr अनुरोधों के लिए आशाजनक लगता है जो महंगा नहीं है, यह एक महान पोस्ट है जो मिडवे परीक्षण का वर्णन करता है, जो अगर मुझे सही समझ में आता है तो आपके नियंत्रक / सेवा को वास्तव में एक e2e परीक्षण की तरह डेटा पुनर्प्राप्त करने देता है, लेकिन आपका मिडवे टेस्ट वास्तविक है नियंत्रक क्षेत्र तक पहुंच (e2e मुझे नहीं लगता)।


2

कर्मा प्रीप्रोसेसर हैं जो JSON फाइलों के साथ भी काम करते हैं। यहाँ एक है:

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

और बेशर्म प्लग, यह एक है जिसे मैंने विकसित किया है जिसमें आवश्यकताएँ समर्थन है

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



1

कैमरन के जवाब के लिए एक विकल्प है , 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();
    });
});

$ .When और $ .getJSON में $ क्या है?
मैट

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.