Loading a mock JSON file within Karma+AngularJS test

前端 未结 8 1462
星月不相逢
星月不相逢 2020-11-28 18:57

I have an AngularJS app set up with tests using Karma+Jasmine. I have a function I want to test that takes a large JSON object, converts it to a format that\'s more consumab

相关标签:
8条回答
  • 2020-11-28 19:12

    There are Karma preprocessors that work with JSON files also. There is one here:

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

    And shameless plug, this is one I developed that has RequireJS support

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

    0 讨论(0)
  • 2020-11-28 19:12

    You can use the karma-html2js-preprocessor to get the json files added to the __html__ global.

    see this answer for details: https://stackoverflow.com/a/22103160/439021

    0 讨论(0)
  • 2020-11-28 19:13

    Here is an alternative to Cameron's answer, without the need for jasmine-jquery nor any extra Karma config, to test e.g. an Angular service using $resource :

    angular.module('myApp').factory('MyService', function ($resource) {
        var Service = $resource('/:user/resultset');
        return {
            getResultSet: function (user) {
                return Service.get({user: user}).$promise;
            }
        };
    });
    

    And the corresponding unit test :

    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();
        });
    });
    
    0 讨论(0)
  • 2020-11-28 19:28

    Serving JSON via the fixture is the easiest but because of our setup we couldn't do that easily so I wrote an alternative helper function:

    Repository

    Install

    $ bower install karma-read-json --save
    
      OR
    
    $ npm install karma-read-json --save-dev
    
      OR
    
    $ yarn add karma-read-json --dev
    

    Usage

    1. Put karma-read-json.js in your Karma files. Example:

      files = [
        ...
        'bower_components/karma-read-json/karma-read-json.js',
        ...
      ]
      
    2. Make sure your JSON is being served by Karma. Example:

      files = [
        ...
        {pattern: 'json/**/*.json', included: false},
        ...
      ]
      
    3. Use the readJSON function in your tests. Example:

      var valid_respond = readJSON('json/foobar.json');
      $httpBackend.whenGET(/.*/).respond(valid_respond);
      
    0 讨论(0)
  • 2020-11-28 19:33

    looks like your solution is the right one but there are 2 things i don't like about it:

    • it uses jasmine
    • it requires new learning curve

    i just ran into this problem and had to resolve it quickly as i had no time left for the deadline, and i did the following

    my json resource was huge, and i couldn't copy paste it into the test so i had to keep it a separate file - but i decided to keep it as javascript rather than json, and then i simply did:

    var someUniqueName = ... the json ...

    and i included this into karma conf includes..

    i can still mock a backend http response if needed with it.

    $httpBackend.whenGET('/some/path').respond(someUniqueName);

    i could also write a new angular module to be included here and then change the json resource to be something like

    angular.module('hugeJsonResource', []).constant('SomeUniqueName', ... the json ... );

    and then simply inject SomeUniqueName into the test, which looks cleaner.

    perhaps even wrap it in a service

    angular.module('allTestResources',[]).service('AllTestResources', function AllTestResources( SomeUniqueName , SomeOtherUniqueName, ... ){
       this.resource1 = SomeUniqueName;
       this.resource2 = SomeOtherUniqueName; 
    })
    

    this solutions was faster to me, just as clean, and did not require any new learning curve. so i prefer this one.

    0 讨论(0)
  • 2020-11-28 19:33

    I was looking for the same thing. I'm going to try this approach. It uses the config files to include the mock data files, but the files are a little more than json, because the json needs to be passed to angular.module('MockDataModule').value and then your unit tests can also load multiple modules and then the value set is available to be injected into the beforeEach inject call.

    Also found another approach that looks promising for xhr requests that aren't costly, it's a great post that describes midway testing, which if I understand right lets your controller/service actually retrieve data like in an e2e test, but your midway test has actual access to the controller scope (e2e doesn't I think).

    0 讨论(0)
提交回复
热议问题