本文介绍了如何在不使用 TestBed 的情况下模拟 Angular 中的 http 帖子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何对这个登录功能进行单元测试,特别是 http post 部分?我制作的 http 模拟没有正确编码,无法进入代码的if...else"部分.我不想使用 TestBed.测试床太慢了.

How do I unit test this login function, specifically the http post part? The http mock I made is not coded correctly to get into the 'if...else' section of the code. I dont want to use TestBed. TestBed is too slow.

login(username: string, password: string): Observable<boolean> {

    const headers = new Headers();
    headers.append('Content-Type', 'application/json');
    headers.append('accept', 'application/json');
    let options = new RequestOptions({ headers: headers });

    return this.http.post('https://blah/api/login',
      JSON.stringify({ username: username, password: password }), options)
        .map((response: Response) => {
            const token = response.json() && response.json().access_token;
            if (token) {
                this.token = token;
                localStorage.setItem('currentUser', JSON.stringify({ username: username, token: token }));
                return true;
            } else {
                return false;
            }
        }).catch(this._serverError);
}

private _serverError(err: any) {
    return Observable.throw(err || 'backend server error');
}

下面是我尝试的 Jasmine 测试:我需要这方面的帮助.


Below is the Jasmine test Im attempting: I need help with this line.

spyOn(mockHttp,'post').and.returnValue(Observable.of(response));

我的 returnValue 应该是什么才能让我进入登录函数中的if...else"代码?

What should my returnValue be to get my inside of the 'if...else' code in the login function?

    describe('AuthenticationService', () => {
      let service: AuthenticationService;
      let mockHttp = null;

      beforeEach(() => {
        mockHttp = {};
        mockHttp.post = function(){};
        service = new AuthenticationService(mockHttp);
     });

    it(`should set access token in local storage for successful login`,() => {
      const access_token = 'blah83balc380';
      const responseOptions =  new ResponseOptions();
      responseOptions.status = 200;
      responseOptions.body = {access_token:access_token};
      const username = 'test';
      const currentUserExpected = JSON.stringify({ username: username, token: access_token });
      var response = new Response(responseOptions);
      spyOn(mockHttp,'post').and.returnValue(Observable.of(response));
      service.login(username, 'test');
      var currentUser = localStorage.getItem('currentUser');
      expect(currentUserExpected).toEqual(currentUser);
    });
  });

推荐答案

这是我最终使用的答案.当我可以像下面的代码一样使用 TestBed 时,我以一种很慢的方式使用 TestBed:

This is the answer that I ended up using. I was using TestBed in a way that was slow when I could have been using TestBed like the code below:

import { TestBed, inject} from '@angular/core/testing';
import { HttpModule,  XHRBackend, Response, ResponseOptions } from '@angular/http';
import { AuthenticationService } from '../_services/authentication.service';
import { MockBackend } from '@angular/http/testing';

describe('AuthenticationService', () => {
  let mockbackend, service;

  beforeEach(() => {
    localStorage.clear();
    TestBed.configureTestingModule({
      imports: [ HttpModule ],
      providers: [
        AuthenticationService,
        { provide: XHRBackend, useClass: MockBackend }
      ]
    });
  });

  beforeEach(inject([AuthenticationService, XHRBackend], (_service,
_mockbackend) => {
    service = _service;
    mockbackend = _mockbackend;
  }));

  it('should set access token in local storage for successful login', () =>
 {
    const access_token = 'blah83balc380';
    const username = 'test';
    const currentUserExpected = JSON.stringify({ username: username, token: access_token });
    const response = {access_token: access_token};
    const responseOptions = new ResponseOptions();
    responseOptions.body = JSON.stringify(response);
    mockbackend.connections.subscribe(connection => {
      connection.mockRespond(new Response(responseOptions));
    });
    service.login(username, 'test').subscribe(respond => {
      expect(respond).toEqual(true);
      const currentUser = localStorage.getItem('currentUser');
      expect(currentUserExpected).toEqual(currentUser);
    });
  });

it('should not set access token in local storage for unsuccessful login', () =>     {
    const username = 'test';
    const responseOptions = new ResponseOptions();
    responseOptions.body = '';
    responseOptions.status = 401;
    const response = new Response(responseOptions);
    response.ok = false;
    response.statusText = 'Unauthorized';
    response.type = 2;

    mockbackend.connections.subscribe(connection => {
      connection.mockRespond(response);
    });
    service.login(username, 'test').subscribe(respond => {
      expect(respond).toEqual(false);
    }, err => {
      const currentUser = localStorage.getItem('currentUser');
      expect(currentUser).toEqual(null);
    });
  });
});

这篇关于如何在不使用 TestBed 的情况下模拟 Angular 中的 http 帖子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 04:22