最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular 2 JWT Unit Testing - Stack Overflow

programmeradmin3浏览0评论

My API calls are authenticated with JWT. I am trying to write code for a service method. All requests has this interceptor:

public interceptBefore(request: InterceptedRequest): InterceptedRequest {
        // Do whatever with request: get info or edit it
        this.slimLoadingBarService.start();
        let currentUser = JSON.parse(localStorage.getItem('currentUser'));
        if (currentUser && currentUser.data.token) {
            request.options.headers.append('Authorization', 'Bearer ' + currentUser.data.token);
        }
        return request;
    }

Service method that I want to test:

getAll(page: number, pageSize: number, pany: string): Observable<any> {
        return this.http.get(`${this.conf.apiUrl}/jobs`)
            .map((response: Response) => response.json());
    }

Started the code for it:

import { MockBackend, MockConnection } from '@angular/http/testing';
import { Http, BaseRequestOptions, Response, ResponseOptions, RequestMethod } from '@angular/http';
import { JobListService } from './job-list.service';
import { inject, TestBed } from '@angular/core/testing/test_bed';
import { JOBLISTMOCK } from '../mocks/job-list.mock';

fdescribe('Service: JobListService', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                JobListService,
                MockBackend,
                BaseRequestOptions,
                {
                    provide: Http,
                    useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
                        return new Http(backend, defaultOptions);
                    },
                    deps: [MockBackend, BaseRequestOptions]
                },
            ]
        });
    });

    it('should create a service', inject([JobListService], (service: JobListService) => {
        expect(service).toBeTruthy();
    }));

    describe('getAll', () => {
        it('should return jobs', inject([JobListService, MockBackend], (service: JobListService, backend: MockBackend) => {
            let response = new ResponseOptions({
                body: JSON.stringify(JOBLISTMOCK)
            });

            const baseResponse = new Response(response);

            backend.connections.subscribe(
                (c: MockConnection) => c.mockRespond(baseResponse)
            );

            return service.getAll(1, 10, '18').subscribe(data => {
                expect(data).toEqual(JOBLISTMOCK);
            });
        }));
    });
});

Do not know how to test it against the interceptor.

PS: As the tests are now, getting an error:

1) should create a service
     JobListService
     TypeError: null is not an object (evaluating 'this.platform.injector') in src/test.ts (line 83858)
_createCompilerAndModule@webpack:///~/@angular/core/testing/test_bed.js:254:0 <- src/test.ts:83858:44

2) should return jobs
     JobListService getAll
     TypeError: null is not an object (evaluating 'this.platform.injector') in src/test.ts (line 83858)
_createCompilerAndModule@webpack:///~/@angular/core/testing/test_bed.js:254:0 <- src/test.ts:83858:44

My API calls are authenticated with JWT. I am trying to write code for a service method. All requests has this interceptor:

public interceptBefore(request: InterceptedRequest): InterceptedRequest {
        // Do whatever with request: get info or edit it
        this.slimLoadingBarService.start();
        let currentUser = JSON.parse(localStorage.getItem('currentUser'));
        if (currentUser && currentUser.data.token) {
            request.options.headers.append('Authorization', 'Bearer ' + currentUser.data.token);
        }
        return request;
    }

Service method that I want to test:

getAll(page: number, pageSize: number, pany: string): Observable<any> {
        return this.http.get(`${this.conf.apiUrl}/jobs`)
            .map((response: Response) => response.json());
    }

Started the code for it:

import { MockBackend, MockConnection } from '@angular/http/testing';
import { Http, BaseRequestOptions, Response, ResponseOptions, RequestMethod } from '@angular/http';
import { JobListService } from './job-list.service';
import { inject, TestBed } from '@angular/core/testing/test_bed';
import { JOBLISTMOCK } from '../mocks/job-list.mock';

fdescribe('Service: JobListService', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                JobListService,
                MockBackend,
                BaseRequestOptions,
                {
                    provide: Http,
                    useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
                        return new Http(backend, defaultOptions);
                    },
                    deps: [MockBackend, BaseRequestOptions]
                },
            ]
        });
    });

    it('should create a service', inject([JobListService], (service: JobListService) => {
        expect(service).toBeTruthy();
    }));

    describe('getAll', () => {
        it('should return jobs', inject([JobListService, MockBackend], (service: JobListService, backend: MockBackend) => {
            let response = new ResponseOptions({
                body: JSON.stringify(JOBLISTMOCK)
            });

            const baseResponse = new Response(response);

            backend.connections.subscribe(
                (c: MockConnection) => c.mockRespond(baseResponse)
            );

            return service.getAll(1, 10, '18').subscribe(data => {
                expect(data).toEqual(JOBLISTMOCK);
            });
        }));
    });
});

Do not know how to test it against the interceptor.

PS: As the tests are now, getting an error:

1) should create a service
     JobListService
     TypeError: null is not an object (evaluating 'this.platform.injector') in src/test.ts (line 83858)
_createCompilerAndModule@webpack:///~/@angular/core/testing/test_bed.js:254:0 <- src/test.ts:83858:44

2) should return jobs
     JobListService getAll
     TypeError: null is not an object (evaluating 'this.platform.injector') in src/test.ts (line 83858)
_createCompilerAndModule@webpack:///~/@angular/core/testing/test_bed.js:254:0 <- src/test.ts:83858:44
Share Improve this question edited Feb 10, 2017 at 9:30 DilumN 2,8956 gold badges32 silver badges45 bronze badges asked Feb 10, 2017 at 3:49 yretutayretuta 8,11118 gold badges84 silver badges154 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7 +250

TypeError: null is not an object (evaluating 'this.platform.injector')

Generally you will get this error if you haven't initialized the test environment correctly. You could solve this problem by doing the following

import {
  BrowserDynamicTestingModule, platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
...
beforeAll(() => {
  TestBed.initTestEnvironment(
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting()
  );
});

The thing about this though, is that it should only be called once for the entire test suite execution. So if you have it in every test file, then you need to reset it first in each file

beforeAll(() => {
  TestBed.resetTestEnvironment();
  TestBed.initTestEnvironment(
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting()
  );
});

Better than this though, is to not add it in each test file. If you look at the Angular docs for Webpack integration, in the testing section, you will see a file karma-test-shim.js. In this file is the remended way to initialize the test environment

Error.stackTraceLimit = Infinity;

require('core-js/es6');
require('core-js/es7/reflect');

require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');

var appContext = require.context('../src', true, /\.spec\.ts/);

appContext.keys().forEach(appContext);

var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');

testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule,
    browser.platformBrowserDynamicTesting());

You can see at the bottom where we make the same initialization call as above. You should add this file to the karma.conf.js file in the files array in the configuration. This is from the linked documentation above

files: [
  {pattern: './config/karma-test-shim.js', watched: false}
],

preprocessors: {
  './config/karma-test-shim.js': ['webpack', 'sourcemap']
},
发布评论

评论列表(0)

  1. 暂无评论