Angular学习笔记69:Angular项目的单元测试 -- 对服务进行测试

对服务进行测试

服务通常是单元测试中最简单的文件类型

对于简单,没有其他依赖的服务

对于一个没有其他依赖的服务,Mock 一些数据,进行测试即可

例如:对于一个公共数据处理的服务

import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PublicDataService {

  private themeColor = null;
  private tenementList: Array<any>;     // 租户List
  public themeSubject = new Subject<any>();

  constructor() {
  }

  // tenementList Set方法  -- 用于从projectindex -> myproject 中
  public setTenementList(list): void {
    this.tenementList = list;
    const tenementhandledList = [];
    this.tenementList.forEach(tenement => {
      const projectList = [];
      tenement.comSystems.forEach(project => {
        const projectObject = {
          value: project.id,
          label: String(project.tagName).toUpperCase() + '-' + project.projectName,
          isLeaf: true
        };
        projectList.push(projectObject);
      });
      const tenementObject = {
        value: tenement.id,
        label: tenement.tenantName,
        children: projectList,
      };
      tenementhandledList.push(tenementObject);
    });
    this.tenementList = tenementhandledList;
  }

  // tenementList Get方法  -- 用于从projectindex -> myproject 中
  public getTenementList(): Array<any> {
    return this.tenementList;
  }
  // 设置主题
  public setTheme(theme: string): void {
    switch (theme) {
      case '0':
        this.themeColor = 'green-theme';
        break;
      case '1':
        this.themeColor = 'blue-theme';
        break;
      case '2':
        this.themeColor = 'red-theme';
        break;
    }
    window.localStorage.setItem('platformTheme', this.themeColor);
    this.themeSubject.next(this.themeColor);
  }

  public getTheme(): string {
    return this.themeColor;
  }

}

在测试文件中,既可以使用TestBed创建一个 服务的实例进行测试,也可以直接 new 一个实例出来进行测试。

import {TestBed} from '@angular/core/testing';

import {PublicDataService} from './public-data.service';

describe('PublicDataService', () => {
  let publicDataService: PublicDataService;
  beforeEach(() => {
    publicDataService = new PublicDataService();
    TestBed.configureTestingModule({});
  });
  
  it('should be created', () => {
    const service: PublicDataService = TestBed.get(PublicDataService);
    expect(service).toBeTruthy();
  });

  it('should test function setTheme is green-theme', () => {
    publicDataService.setTheme('0');
    expect(window.localStorage.getItem('platformTheme')).toBe('green-theme');
    expect(publicDataService.getTheme()).toBe('green-theme');
    publicDataService.themeSubject.subscribe(theme => {
      expect(theme).toBe('green-theme');
    });
  });

  it('should test function setTheme is blue-theme', () => {
    publicDataService.setTheme('1');
    expect(window.localStorage.getItem('platformTheme')).toBe('blue-theme');
    expect(publicDataService.getTheme()).toBe('blue-theme');
    publicDataService.themeSubject.subscribe(theme => {
      expect(theme).toBe('blue-theme');
    });
  });

  it('should test function setTheme is red-theme', () => {
    publicDataService.setTheme('2');
    expect(window.localStorage.getItem('platformTheme')).toBe('red-theme');
    expect(publicDataService.getTheme()).toBe('red-theme');
    publicDataService.themeSubject.subscribe(theme => {
      expect(theme).toBe('red-theme');
    });
  });
});

  • TestBed 方式的测试
it('should be created', () => {
    const service: PublicDataService = TestBed.get(PublicDataService);
    expect(service).toBeTruthy();
  });

在这里通过 TestBed 的 get() 方法去创建了一个PublicDataService类型的service,然后在断言service的可否正确创建。

  • 非 TestBed 方式的测试
it('should test function setTheme is green-theme', () => {
    publicDataService.setTheme('0');
    expect(window.localStorage.getItem('platformTheme')).toBe('green-theme');
    expect(publicDataService.getTheme()).toBe('green-theme');
    publicDataService.themeSubject.subscribe(theme => {
      expect(theme).toBe('green-theme');
    });
  });

这里的 publicDataService 是在 beforeEach 的函数中创建出来的

beforeEach(() => {
    publicDataService = new PublicDataService();
    TestBed.configureTestingModule({});
  });

然后使用 publicDataService 去调用服务里的方法,然后进行测试用例的断言。

对于有其他依赖的服务

在有些服务中,会涉及到其他注入到构造函数中的服务,在进行单元测试的时候,需要手工创建并注入这些依赖。

例如:

  export class PublicDataService {
  
  private themeColor = null;
  
  constructor(private utilService: UtilService) {
    }
    
    public getLogoName() {
    return this.utilService.getLogoNameWithUtil();
    }
  }

在测试的时候,如何创建呢?

  • 通过真实的服务拿到真实的数据
it('should test function setPipeLineId', () => {
    const publicDataServiceNoBed: PublicDataService = new PublicDataService(new UtilService());
    publicDataServiceNoBed.setPipeLineId(1);
    expect(publicDataServiceNoBed.getPipeLineId()).toBe(1);
  });
  • 通过伪造的数据和伪造的服务对象来测试
it('# getLogoNameWithUtil should return faked value from a fake object', () => {
    const fake = {getLogoNameWithUtil: () => 'fake value'};
    const publicDataServiceAsFake = new PublicDataService(fake as UtilService);
    expect(publicDataServiceAsFake.getLogoName()).toBe('fake value');
  });

需要注意的是:fake中伪造的对象是依赖服务中的方法。getLogoNameWithUtil是UtilService中的方法

  • 通过spy创建一个对象,并使用一个简单的值去测试
it('#getLogoNameWithUtil should return stubbed value from a spy', () => {
    const valueServiceSpy = jasmine.createSpyObj('UtilService', ['getLogoNameWithUtil']);
    const stubValue = 'UtilService stub value';
    valueServiceSpy.getLogoNameWithUtil.and.returnValue(stubValue);
    const publicDataServiceAsSpy = new PublicDataService(valueServiceSpy);
    expect(publicDataServiceAsSpy.getLogoName())
      .toBe(stubValue, 'service returned stub value');
    expect(valueServiceSpy.getLogoNameWithUtil.calls.count())
      .toBe(1, 'spy method was called once');
    expect(valueServiceSpy.getLogoNameWithUtil.calls.mostRecent().returnValue)
      .toBe(stubValue);
  });
  

valueServiceSpy 是jasmine.createSpyObj是以UtilService为基础和getLogoNameWithUtil的方法名创建的对象。
calls.count() 返回spy调用的次数
calls.mostRecent() 以对象形式返回最近一次调用的上下文(this),以及传递的参数
需要注意的是,在使用jasmine.createSpyObj创建的时候,记得将UtilService 添加到providers数组中

TestBed.configureTestingModule({
      providers: [UtilService],
    });

你可能感兴趣的:(Angular)