如何编写用于登录服务的单元测试用例

时间:2019-09-12 10:02:06

标签: angular unit-testing

我是角度7单元测试的新手。我编写了一些测试用例,但是我的代码覆盖率未涵盖其中,请任何人帮助我。下面添加了我的登录service.ts文件和spec.ts文件。 我是角度7单元测试的新手。我编写了一些测试用例,但是我的代码覆盖率未涵盖其中。请任何人帮助我。下面添加了我的login service.ts文件和spec.ts文件。

我的login.service.ts文件

import { Router } from '@angular/router';
import { Utility } from '../../shared/utility.module';
import { User } from './../Models/user.model';
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map, catchError } from 'rxjs/operators';
import { GenericErrorHandler } from '../../error-handlers/generic.error.handler';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoginService {
  serverUrl = 'https://www.livepaperapi.com/';
  errorData: {};
  private isUserLoggedIn = new Subject<boolean>();
  isUserLoggedIn$ = this.isUserLoggedIn.asObservable();
  private utility: Utility;
  constructor(private http: HttpClient, private router: Router) {
    this.utility = new Utility();
  }

  login(username: string, password: string) {
    const headers: HttpHeaders = new HttpHeaders({
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: 'Basic ' + btoa(username + ':' + password)
    });

    return this.http
      .post<User>(
        `${this.serverUrl}auth/v2/token`,
        'grant_type=client_credentials&scope=default',
        { headers }
      )
      .pipe(catchError(GenericErrorHandler.handleError))
      .pipe(
        map(user => {
          if (user && user.accessToken) {
            this.utility.storeUserAccessToken(user.accessToken);
            this.isUserLoggedIn.next(true);
            return true;
          }
          this.isUserLoggedIn.next(false);
          return false;
        })
      );
  }

  get isLoggedIn(): boolean {
    return this.utility.isStoredTokenValid();
  }

  getAuthorizationToken() {
    return this.utility.getUserAccessToken();
  }

  logout() {
    this.utility.deleteUserAccessToken();
    this.router.navigate(['']);
    this.isUserLoggedIn.next(false);
  }
}

我的login.service.spec.ts

import { TestBed, inject, fakeAsync, tick } from '@angular/core/testing';
import { LoginService } from './login.service';
import { CommonTestModules } from '../../shared/common.test.modules';
import {
  HttpClientTestingModule,
  HttpTestingController
} from '@angular/common/http/testing';
import { User } from './../Models/user.model';

describe('LoginService', () => {
  beforeEach(() =>
    TestBed.configureTestingModule({
      imports: [CommonTestModules, HttpClientTestingModule],
      providers: [LoginService]
    })
  );

  it('should be created', () => {
    const service: LoginService = TestBed.get(LoginService);
    expect(service).toBeTruthy();
  });

  it(
    'should perform login correctly',
    fakeAsync(
      inject(
        [LoginService, HttpTestingController],
        (loginService: LoginService, backend: HttpTestingController) => {

          // Set up
          const url = 'https://www.livepaperapi.com/auth/v2/token';
          const responseObject = {
            "serviceName": "auth",
            "apiVersion": "2.0",
            "accessToken": "YW5kcmg3aDV1",
            "scope": "default"
          }

          let response = null;
          const mockResponse = {
            status: '200'
          };
          let username = "hpzp8yyo5l6f9e8lbqqy4748xt7yc8hc";
          let password = "rpcB8VAZHT1XXePgHDahOXD9r0kDpRBL";
          loginService.login(username, password).subscribe(
            (receivedResponse: any) => {
              response = receivedResponse;
              expect(mockResponse.status.toString()).toEqual('200');
            },
            (error: any) => {}
          );

          const requestWrapper = backend.expectOne({url: 'https://www.livepaperapi.com/auth/v2/token'});
          requestWrapper.flush(responseObject);

          tick();

          expect(requestWrapper.request.method).toEqual('POST');

        }
      )
    )
  );


});

1 个答案:

答案 0 :(得分:0)

您的测试文件应如下所示:

import { TestBed, inject, fakeAsync, tick } from '@angular/core/testing';
import { LoginService } from './login.service';
import { CommonTestModules } from '../../shared/common.test.modules';
import {
  HttpClientTestingModule,
  HttpTestingController
} from '@angular/common/http/testing';
import { User } from './../Models/user.model';

describe('LoginService', () => {
    let service: LoginService;
    let httpMock: HttpTestingController;

  beforeEach(() =>
    TestBed.configureTestingModule({
      imports: [CommonTestModules, HttpClientTestingModule],
      providers: [LoginService]
    });

    service = TestBed.get(LoginService);
    httpMock = TestBed.get(HttpTestingController);
  );

  it('should be created', () => {
    expect(service).toBeTruthy();
  });

  it(
    'should perform login correctly',
    (done) => {

          // Set up
          const url = 'https://www.livepaperapi.com/auth/v2/token';
          const responseObject = {
            "serviceName": "auth",
            "apiVersion": "2.0",
            "accessToken": "YW5kcmg3aDV1",
            "scope": "default"
          }

          let response = null;
          const mockResponse = {
            status: '200'
          };
          let username = "hpzp8yyo5l6f9e8lbqqy4748xt7yc8hc";
          let password = "rpcB8VAZHT1XXePgHDahOXD9r0kDpRBL";
          loginService.login(username, password).subscribe(
            (receivedResponse: any) => {
              response = receivedResponse;
              expect(mockResponse.status.toString()).toEqual('200');

              done();
            },
            (error: any) => {}
          );

          const requestWrapper = httpMock.expectOne({url: 'https://www.livepaperapi.com/auth/v2/token'});
          expect(requestWrapper.request.method).toEqual('POST');
          requestWrapper.flush(responseObject);
        }
      )
    )
  );
});

注意:

  1. service和httpMock是在beforeEach中定义的,因此您可以避免在每个测试用例中进行注入。

  2. fakeAsync + tick已替换为使用done()方法(https://jasmine.github.io/tutorials/async#callbacks)({{3}})的常见异步测试方法

相关问题