使用MockBackend的Angular 2/4测试服务返回undefined

时间:2017-06-21 06:15:31

标签: angular unit-testing jasmine karma-jasmine

我每次以{}收到回复时都会使用MockBackend为我的服务编写单元测试。

我引用了以下网址寻求解决方案: https://angular.io/api/http/testing/MockBackend

感谢任何帮助。

这是我的服务:

import {Injectable} from '@angular/core';
import { Http, Headers, Response, RequestOptions } from '@angular/http';
import {LoginResult} from './models';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthService {
    private _loginUrl = '/api/login';
    private _logoutUrl = '/api/logout';
    private headers = new Headers({ 'Content-Type': 'application/json' });
    private options = new RequestOptions({ headers: this.headers });
    private _isAuthenticated:boolean;

    constructor(private _http:Http) {}

    isAuthenticated():boolean {
        return this._isAuthenticated;
    }

    setUserLoggedIn(authStatus: boolean) {
        this._isAuthenticated = authStatus;
    }

    login(username:string, password:string) {
        let body = JSON.stringify({username: username, password: password});
        return this._http.post(this._loginUrl, body, this.options)
            .map(res => res.json());
    }
}

这是我的测试:

import {async, fakeAsync, TestBed, tick} from '@angular/core/testing';
import { HttpModule, Http, ConnectionBackend, XHRBackend, RequestOptions, BaseRequestOptions, ResponseOptions} from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import { ReflectiveInjector } from '@angular/core';
import { AuthService } from './auth.service';
import { LoginResult } from './models';

export const loginData = {
    "userId": "593732e2d3d20e1b852dc463",
    "username": "xyz",
    "roles": [
        "ROLE1",
        "ROLE2"
    ],
    "token": "e26c2b7b-c60f-404d-94d5-d35446fd2a9c"
};

describe('AuthService', () => {
    beforeEach(() => {
        this.injector = ReflectiveInjector.resolveAndCreate([
            {provide: ConnectionBackend, useClass: MockBackend},
            {provide: RequestOptions, useClass: BaseRequestOptions},
            Http,
            AuthService
        ]);
        this.authService = this.injector.get(AuthService);
        this.backend = this.injector.get(ConnectionBackend) as MockBackend;
    t    his.backend.connections.subscribe((connection: any) => this.lastConnection = connection);
    });

    it('login should query current service url', () => {
        this.authService.login('username', 'password');
        expect(this.lastConnection).toBeDefined('no http service connection t all?');
        expect(this.lastConnection.request.url).toMatch(/api\/login$/, 'url invalid`');
    });

    it('login', fakeAsync(() => {
        let result: any;
        this.authService.login('username', 'password')
            .subscribe(response => {
                console.log('Response :::' + JSON.stringify(response));
                result = response;
            })
        this.lastConnection.mockRespond(new Response(new ResponseOptions({
         body: JSON.stringify(loginData),
       })));
        tick();
        expect(result).toBeDefined();
    }));

    it('login while server is down', fakeAsync(() => {
        let result: LoginResult;
        let loginError: any;
        this.authService.login('username', 'password')
            .subscribe(response => {
                console.log('Response1 :::' + JSON.stringify(response));
                result = response;
            }, (error: any) => { loginError = error; });
        this.lastConnection.mockRespond(new Response(new ResponseOptions({
                status: 404,
                statusText: 'URL not found.'
            })));
        tick();
        expect(result).toBeUndefined();
        expect(loginError).toBeDefined();
    }));
});

1 个答案:

答案 0 :(得分:2)

看起来你使用来自es6.lib的响应,但你需要一个来自Angular http。

的响应
import {Response} from '@angular/http';