angular karma unit test using $httpBackend + $reso

2019-09-10 02:50发布

Requirements

  • Angular based REST client component
  • Must interact between a private API and services
  • Karma/Jasmine test does not bootstrap app module

Current dilemma

We do not want to bootstrap the entire application for unit tests (using module() or angular.mock.module()). It does not seem sustainable for an enterprise level application, even though Angular's component registration is a useful feature. All the examples I have found do it this way, however per our current business objectives, I need to do it without bootstrapping the app module.

So far I have successfully injected both $resource and $httpBackend and they are functional. I can assign a respond behavior to the $httpBackend object, and I can inject $resource into the restClient factory in the test suite. However when I try to run it, it appears that they are not aware of each other, and therefore the client is actually sending calls (undesirable #1), leaving the $httpBackend object waiting with outstanding expectations and nothing to flush (#2).

Please help

Can you point out the configuration errors I'm missing to get these two pieces to work together with out calling module()?

Testing errors

Error: No pending request to flush !
        at Function.$httpBackend.flush (node_modules/angular-mocks/angular-mocks.js:1544:34)
        at Object.<anonymous> (/var/folders/8h/lqyqq1ks6vv8z5mpsxjqn5sw0000gn/T/89bece8e9480f44013f53b3f1b05b4ba.browserify:855:22 <- src/app/services/restClient_test.js:24:0)
Error: Unsatisfied requests: GET https://ourlink.nl
        at Function.$httpBackend.verifyNoOutstandingExpectation (node_modules/angular-mocks/angular-mocks.js:1577:13)
        at Object.<anonymous> (/var/folders/8h/lqyqq1ks6vv8z5mpsxjqn5sw0000gn/T/89bece8e9480f44013f53b3f1b05b4ba.browserify:847:22 <-

Browser error from failed restClient XHR

XMLHttpRequest cannot load undefinedhttps://oursite.nl?userId=UserZ. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

restClient.js:

function restClient ($resource, baseUrl) {
    'use strict';

    return {
        get: get
    };

    function get (route, options) {
        var self = this;
        var payload = $resource(self.baseUrl + route, options).get(options.routeParams);
        return payload;
    }
}

module.exports = restClient;

restClient_test.js:

describe('restClient', function () {
    var client, $httpBackend;

    beforeEach(inject(function(_$httpBackend_) {
        $httpBackend = _$httpBackend_;
    }));

    beforeEach(function () {
        var $injector = angular.injector(['ng', 'ngResource']);
        this.client = require('./restClient.js');
        client = this.client($injector.get('$resource'));
    });

    afterEach(function() {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    it('sends a get request', function () {
        $httpBackend.expectGET('https://oursite.nl')
            .respond('200', {userId: 'UserZ'}, {token: '1234'});
        client.get('https://oursite.nl', {userId: 'UserZ'});
        $httpBackend.flush();
    });
});

1条回答
ゆ 、 Hurt°
2楼-- · 2019-09-10 03:22

Without using ngMock Jasmine/Mocha helpers it has to be something like this:

describe('restClient', function () {
    var $injector, client, $httpBackend;

    beforeEach(function () {
        $injector = angular.injector(['ng', 'ngResource', 'ngMock']);
        $httpBackend = $injector.get('$httpBackend');
        this.client = require('./restClient.js');
        client = this.client($injector.get('$resource'));
    });
    ...
});
查看更多
登录 后发表回答