当我的登录终点在角度4

时间:2017-09-28 02:55:05

标签: angular unit-testing karma-jasmine

我试图找出当我的登录终点引发错误时如何测试异常。

login.service.ts

import { Injectable } from '@angular/core';
import {Headers, Http, Response} from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import * as _ from 'lodash';

@Injectable()
export class LoginService {
  private loginEndPoint ="http://localhost:2300/login";
  private headers: Headers;

  constructor(
    private http: Http
  ) { }

  loginUser(username: string, password: string) {
    const params = { username, password };

    return this.http.post(`${this.loginEndPoint}login`, params)
      .map(this.getData)
      .catch(this.handleError);
  }

  getData(res: Response) {
    return res.text();
  }

  handleError(error: Response | any) {
    console.error(error);
    return Observable.throw(error);
  }
}

login.service.spec.ts

import {async,getTestBed,TestBed,inject} from '@angular/core/testing';
  import {BaseRequestOptions,Http,Response,ResponseOptions,ResponseType, Request,XHRBackend, HttpModule} from '@angular/http';
  import {MockBackend,MockConnection} from '@angular/http/testing';
  import { LoginService } from './login.service';
  import { Observable } from 'rxjs/Observable';


  class MockError extends Response implements Error {
    type:any
    status:any
    body:any
    name:any
    message:any
  }

  describe('Service: LoginService', () => {
    let backend:MockBackend;
    let service:LoginService;
    let mockBackend:MockBackend;
    let loginService:LoginService;

    beforeEach(() => {

      TestBed.configureTestingModule({
        imports: [HttpModule],
        providers: [
          {provide:"http://localhost:2300/login", useValue: 'http://example.com'},
          LoginService,
          {provide: XHRBackend, useClass: MockBackend},
        ]
      });
    });


    describe('loginUser()', () => {
      it('should return a token if login succeeds',
        inject([LoginService, XHRBackend], (loginService, mockBackend) => {

          let mockResponse = "token";

          mockBackend.connections.subscribe((connection) => {
            connection.mockRespond(new Response(new ResponseOptions({
              body: mockResponse,
              status: 200
            })));
          });

          loginService.loginUser("username", "password").subscribe((response) => {
            expect(response).toBe("token");
          });
        }));

      it('should return a fail if login fails',
        inject([LoginService, XHRBackend], (loginService, mockBackend) => {

          let mockResponse = {
            "timestamp": 1506545997380,
            "status": 401,
            "error": "Unauthorized",
            "message": "Authentication Failed: Bad credentials",
            "path": "/login"
          };
          let opts = {type: ResponseType.Error, status: 401, body: mockResponse};
          let responseOpts = new ResponseOptions(opts);

          mockBackend.connections.subscribe((connection) => {
            connection.mockError(new Response(responseOpts));
          });

            loginService.loginUser("username", "password").subscribe((response) => {
            expect(loginService.handleError).toHaveBeenCalled();
          });            }));
    });
  });

代码抛出错误如下,并且测试失败。

Chrome 61.0.3163 (Mac OS X 10.11.6): Executed 1 of 29 SUCCESS (0 secs / 0.086 secs)
ERROR: Response{_body: Object{timestamp: 1506545997380, status: 401, error: 'Unauthorized', message: 'Authentication Failed: Bad credentials', path: '/login'}, status:Chrome 61.0.3163 (Mac OS X 10.11.6) Service: LoginService loginUser() should return a fail if login fails FAILED
Response with status: 401 null for URL: null thrown
Chrome 61.0.3163 (Mac OS X 10.11.6): Executed 2 of 29 (1 FAILED) (0 secs / 0.114 secs)

我想测试是否已调用handleError。我试过添加间谍但没有运气。有人可以帮忙吗?我没有理解这有什么问题。可以帮助一些人

1 个答案:

答案 0 :(得分:0)

没关系,我想通了。感谢您查看它。解决方案很简单。

loginService.loginUser("username", "password").subscribe((response) => {
 }, e=> {
  expect(console.error).toHaveBeenCalled();
});