简体   繁体   English

Angular 2 JWT单元测试

[英]Angular 2 JWT Unit Testing

My API calls are authenticated with JWT. 我的API调用使用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, company: 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: PS:正在进行测试,收到错误:

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

TypeError: null is not an object (evaluating 'this.platform.injector') TypeError:null不是对象(评估'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 . 如果你看一下Webpack集成的Angular文档,在测试部分 ,你会看到一个文件karma-test-shim.js In this file is the recommended 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. 您应该将此文件添加到配置中的files数组中的karma.conf.js文件中。 This is from the linked documentation above 这来自上面的链接文档

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

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

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

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