首页 > 解决方案 > 角度单元测试方法调用服务方法

问题描述

**How can I test below method using Jasmin & Karma. Requirement is to cover all the lines** 

我的方法是只调用这个方法。但没有获得代码覆盖率。需要覆盖所有代码行。我在声纳立方体中的代码覆盖率非常低。

  public getNavList() {
        this.navSrv.getNavList().subscribe(list => {
          list.forEach(element => {
            if (element.parentId === 0) {
              this.mainNavs.splice(element.orderNumber, 0, {
                mainMenuTitle: element.name,
                subMenusList: [], id: element.id
              });
            }
          });
          this.mainNavs.forEach((element) => {
            list.forEach(e => {
              if (e.parentId === element.id) {
                element.subMenusList.push(e.name);
              }
            });
          });
          this.selectedModule = this.mainNavs[0].mainMenuTitle.toString().replace(/\s/g, '');
          this.userClickedSubNav = this.mainNavs[0].subMenusList[0].toString().replace(/\s/g, '');
          this.router.navigateByUrl(this.selectedModule + '/' + this.userClickedSubNav.toString().replace(/\s/g, ''));
        });
     
      }

这是我的方法,在 beforeEach() & inside 描述所有 it 块被执行之后

  it('Test getNavList() returns array', () => {
    const arr = [
      {id: 1, name: "CHANGE Card", parentId: 0, orderNumber: 0},
      {id: 2, name: "Account", parentId: 1, orderNumber: 0},
      {id: 3, name: "Activity", parentId: 1, orderNumber: 1},
      {id: 4, name: "Statements", parentId: 1, orderNumber: 2},
      {id: 5, name: "Transfers", parentId: 1, orderNumber: 3},
      {id: 6, name: "Bill Pay", parentId: 1, orderNumber: 4},
      {id: 7, name: "Rewards", parentId: 0, orderNumber: 1},
      {id: 8, name: "TBA", parentId: 7, orderNumber: 0},
      {id: 25, name: "Register", parentId: 1, orderNumber: 5}
    ];
    jasmine.createSpy('getNavList').and.returnValues(of(
      arr
      ));
      component.getNavList();
      const val = component.userClickedSubNav;
      expect(typeof(val)).toBe('object');
  });

以下是 beforeEach() 和 describe() 所有 it() 块执行后的测试设置

import { ComponentFixture, TestBed, waitForAsync, getTestBed } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { of } from 'rxjs';
import { throwError } from 'rxjs';
import { LoginService } from '../../services/main/login/login.service';
import { LoginComponent } from './login.component';
import { AppModule } from '../../app.module';
import { TestUtils } from '../../../TestUtils';
import { MatDialogModule } from '@angular/material/dialog';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { NavService } from 'src/app/services/main/nav/nav.service';

let component: LoginComponent;
let loginServ: LoginService;
let navServ: NavService;

let fixture: ComponentFixture<LoginComponent>;
let testUtils: TestUtils;
let injector: TestBed;
const config = {
  imports: [
    AppModule, MatDialogModule, HttpClientTestingModule
  ],
  providers: [],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
};

function initBeforeEach() {
  TestBed.configureTestingModule(config).compileComponents();
  fixture = TestBed.createComponent(LoginComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
  testUtils = new TestUtils(fixture);
  initInstances();
}

function initInstances(): void {
  injector = getTestBed();
  loginServ = injector.get(LoginService);
}

describe('LoginComponent', () => {

  beforeEach(waitForAsync(() => {
    initBeforeEach();
  }));

});

标签: angularjasminekarma-jasminekarma-runner

解决方案


在 TestBed 模块中将服务作为提供者注入,并提供存根。

class YourServiceStub {
  getNavList() {
    return of(
    [
      {id: 1, name: "CHANGE Card", parentId: 0, orderNumber: 0},
      {id: 2, name: "Account", parentId: 1, orderNumber: 0},
      {id: 3, name: "Activity", parentId: 1, orderNumber: 1},
      {id: 4, name: "Statements", parentId: 1, orderNumber: 2},
      {id: 5, name: "Transfers", parentId: 1, orderNumber: 3},
      {id: 6, name: "Bill Pay", parentId: 1, orderNumber: 4},
      {id: 7, name: "Rewards", parentId: 0, orderNumber: 1},
      {id: 8, name: "TBA", parentId: 7, orderNumber: 0},
      {id: 25, name: "Register", parentId: 1, orderNumber: 5}
    ]
    );
  }
}

const config = {
  imports: [
    AppModule, MatDialogModule, HttpClientTestingModule
  ],
  providers: [{provide: YourServiceClass, useClass: YourServiceStub}],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
};

推荐阅读