使用Jasmine测试加载静态JSON文件的Angular Service

时间:2017-11-23 00:10:35

标签: angular karma-jasmine

我与Testing Services in Angular 2中的指导略有不同,以测试此方法,loadIndex()

loadIndex(): Promise<Response> {
    this.index = null;
    this.isLoaded = false;
    this.isLoading = true;

    const promise = this.client
        .get('./src/assets/data/index.json') // TODO: inject this from config?
        .toPromise();
    promise
        .catch(() => {
            this.isError = true;
            this.isLoaded = false;
        })
        .then(responseOrVoid => {
            const response = <Response>responseOrVoid;
            if (!response) {
                return;
            }

            this.index = response.json().data as Array<BlogEntry>;
            if (!this.index) {
                return;
            }

            this.isLoaded = true;
            this.isLoading = false;
        });

    return promise;
}

进行此测试:

import { TestBed, async, getTestBed } from '@angular/core/testing';
import {
    BaseRequestOptions,
    Http,
    Response,
    ResponseOptions,
    XHRBackend
} from '@angular/http';
import { BlogEntriesService } from './songhay-blog-entries.service';
import { BlogEntry } from '../models/songhay-blog-entry';
import { error } from 'util';

describe('BlogEntriesService', () => {
    const testBed = getTestBed();
    let service: BlogEntriesService;

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                BaseRequestOptions,
                BlogEntriesService,
                {
                    deps: [BaseRequestOptions],
                    provide: Http,
                    useFactory: (
                        backend: XHRBackend,
                        defaultOptions: BaseRequestOptions
                    ) => new Http(backend, defaultOptions)
                }
            ]
        });
    });

    it('should load index', done => {
        service = testBed.get(BlogEntriesService);
        expect(service).toBeDefined();
        expect(service).toBeTruthy();
        service
            .loadIndex()
            .then(result => {
                expect(result).toBeDefined();
            })
            .catch(result => expect(result).toBeUndefined())
            .then(done);
    });
});

我已从测试中删除了MockBackend代码,因为我认为我不需要它,因为我正在加载本地静态JSON文件(不是真正的单元测试)。所以我得到的错误是:

TypeError: Cannot read property 'merge' of undefined

at mergeOptions (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/node_modules/@angular/http/@angular/http.es5.js:1824:1)
    at Http.webpackJsonp.../../../http/@angular/http.es5.js.Http.get (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/node_modules/@angular/http/@angular/http.es5.js:1924:1)
    at BlogEntriesService.webpackJsonp.../../../../../src/app/services/songhay-blog-entries.service.ts.BlogEntriesService.loadIndex (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/src/app/services/songhay-blog-entries.service.ts:78:14)
    at Object.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/src/app/services/songhay-blog-entries.service.spec.ts:39:14)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/node_modules/zone.js/dist/zone.js:392:1)
    at ProxyZoneSpec.webpackJsonp.../../../../zone.js/dist/proxy.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/node_modules/zone.js/dist/proxy.js:79:1)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/node_modules/zone.js/dist/zone.js:391:1)
    at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/node_modules/zone.js/dist/zone.js:142:1)
    at Object.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/../angular.io-index-app/index-app/node_modules/zone.js/dist/jasmine-patch.js:102:1)
    at attemptAsync (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?da99c5b057693d025fad3d7685e1590600ca376d:3945:24)

这个问题在这里已知吗?我应该放弃并建立一个e2e测试吗?

1 个答案:

答案 0 :(得分:1)

代码有DI问题。 Http工厂注入了一个依赖项:

deps: [BaseRequestOptions],

虽然工厂需要2个参数,但它们混在一起。

相反,它应该是:

{
    deps: [XHRBackend, BaseRequestOptions],
    provide: Http,
    useFactory: (
        backend: XHRBackend,
        defaultOptions: BaseRequestOptions
    ) => new Http(backend, defaultOptions)
}

Http提供程序以这种方式定义的唯一原因是因为通常后端在单元测试中被MockBackend替换。如果不是集成测试的情况,请改为HttpModule can be just imported