简体   繁体   English

使用$ httpbackend模拟和打字稿进行单元测试

[英]Unit testing with $httpbackend mocks and typescript

I'm trying to unit test a method that makes an http request with the $http service, however the $httpbackend mock does not seem to be intercepting the request - I get a Error: No pending request to flush ! 我正在尝试对通过$http服务发出http请求的方法进行单元测试,但是$httpbackend模拟似乎并未拦截该请求-我收到一个Error: No pending request to flush ! error. 错误。

My test is as follows: 我的测试如下:

/// <reference path="../typings/tsd.d.ts" />
/// <reference path="../dist/ngJwtAuth.d.ts" />


var expect = chai.expect;

describe('Service tests', () => {

    var $httpBackend:ng.IHttpBackendService;
    var ngJwtAuthService:NgJwtAuth.NgJwtAuthService;

    beforeEach(()=>{

        module('ngJwtAuth');

        inject((_$httpBackend_, _ngJwtAuthService_) => {
            $httpBackend = _$httpBackend_;

            if (!ngJwtAuthService){ //dont rebind, so each test gets the singleton
                ngJwtAuthService = _ngJwtAuthService_; //register injected of service provider
            }
        })
    });

    afterEach(() => {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    it('should be an injectable service', () => {

        return expect(ngJwtAuthService).to.be.an('object');
    });

    it('should retrieve a json web token', () => {

        var user = {
            email: 'joe.bloggs@example.com',
            password: 'password'
        };

        $httpBackend.expectGET('/api/auth/login', (headers) => {
            return headers['Authorization'] == 'Basic '+btoa(user.email+':'+user.password);
        });

        var promisedToken = ngJwtAuthService.authenticate(user.email, user.password);

        promisedToken.then((res) => {

            console.log('res', res);
        });

        $httpBackend.flush();

    });


});

The results I get is 我得到的结果是

Start:
  Service tests
    ✔ should be an injectable service
    ✖ should retrieve a json web token
    ✖ "after each" hook

Finished in 0.055 secs / 0.004 secs

SUMMARY:
✔ 1 tests completed
✖ 2 tests failed

FAILED TESTS:
  Service tests
    ✖ should retrieve a json web token
      Chrome 43.0.2357 (Mac OS X 10.10.3)
    Error: No pending request to flush !
        at Context.<anonymous> (base/test/tmp/test.js?7ade37b85a3e515024b3ce23ba6d9fc4c70ddcc2:104:22)

    ✖ "after each" hook
      Chrome 43.0.2357 (Mac OS X 10.10.3)
    Error: Unsatisfied requests: GET /api/auth/login
        at Context.<anonymous> (base/test/tmp/test.js?7ade37b85a3e515024b3ce23ba6d9fc4c70ddcc2:86:22)

The offending method that I am testing is 我正在测试的冒犯方法是

public authenticate(username:string, password:string): ng.IPromise<Object>{

    var authHeader = NgJwtAuthService.getAuthHeader(username, password);

    var requestConfig:ng.IRequestConfig = {
        method: 'GET',
        url:  this.getLoginEndpoint(),
        headers: {
            Authorization : authHeader
        },
        responseType: 'json'
    };

    return this.$http(requestConfig);
}

The whole project can be found at https://github.com/spira/angular-jwt-auth 整个项目可以在https://github.com/spira/angular-jwt-auth中找到

OK, I worked it out after a bit of playing around. 好吧,我在玩了一会儿之后就解决了。 Turns out the solution was to make sure that $httpbackend was not redeclared for each function. 事实证明,解决方案是确保未为每个函数重新声明$httpbackend This looks like this: 看起来像这样:

inject((_$httpBackend_, _ngJwtAuthService_) => {

    if (!ngJwtAuthService){ //dont rebind, so each test gets the singleton
        $httpBackend = _$httpBackend_;
        ngJwtAuthService = _ngJwtAuthService_; //register injected of service provider
    }
})

As I wanted each test to use the same service (the service is mutable), I had to include the $httpBackend = _$httpBackend_; 因为我希望每个测试使用相同的服务(该服务是可变的),所以我必须包含$httpBackend = _$httpBackend_; line inside the if block. if块内的行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM