【问题标题】:How to write unit test case for a method [Angular]如何为方法编写单元测试用例 [Angular]
【发布时间】:2020-06-30 06:11:47
【问题描述】:

我是 Angular 的初学者。我正在努力学习 Typescript,现在我被告知要为我创建的每个 componentservice 编写 Jasmine 和 Karma 单元测试用例。我看过很多教程来学习Angular 中的单元测试。我是一名实习生,昨天我提出了一个拉取请求,我的技术负责人对此发表了以下评论。

这是我写的代码。

filter-bar.component.ts

import { Component, OnInit, ViewChild, OnDestroy, Input, ChangeDetectorRef } from '@angular/core';
import './filter-bar.component.scss';
import { SisenseService } from '../services/sinsense.service';
import { SisenseConfigService } from '../services/sinsense-config.service';
import { Dashboard, Widget } from 'src/app/shared/models/sisenseConfig';
...

@Component({
    selector: 'app-filter-bar',
    templateUrl: './filter-bar.component.html'
})
export class FilterBarComponent implements OnInit, OnDestroy {
  selectedMembersCount: number;
  dataUnavailable: boolean;

  constructor(
    public sisenseService: SisenseService,
    public sisenseConfigService: SisenseConfigService
  ) {}

  ngOnInit() {
    this.getDataFromWidget();
  }

  getDataFromWidget() {
    this.sisenseService.getWidgetData(
    this.sisenseConfigService.getDashboardId(Dashboard.POPULATION),
    this.sisenseConfigService.getWidgetInfo(Dashboard.POPULATION, Widget.UNIQUE_LIVES).id,
      widgetData => {
        this.selectedMembersCount = widgetData.queryResult.value.data;
        this.changeDetector.detectChanges();
      },
      () => {
        this.dataUnavailable = true;
      }
    );
  }
}

这是我编写的规范文件:

filter-bar.component.spec.ts

import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { FilterBarComponent } from './filter-bar.component';
import { SisenseFilterService } from '../services/sinsense-filter.service';
import { PopUpService } from '@wuitk6/angular/components/popup/popup.service';
import { SisenseService } from '../services/sinsense.service';
import { SisenseConfigService } from '../services/sinsense-config.service';

describe('FilterPanelComponent', () => {
    let component: FilterBarComponent;
    let fixture: ComponentFixture<FilterBarComponent>;

    mockSisenseConfigService.getWidgetInfo.and.returnValue({ id: 'demo_ID' });

        fixture = TestBed.createComponent(FilterBarComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });
});

这是服务,(我不知道谁写了这段代码):

sisense-config.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/do';
...
import { ErrorService } from './error.service';

// This is to avoid compile errors in typescript.
// The real variable will be added when sisense.js is loaded
declare var Sisense: any;

@Injectable({
    providedIn: 'root'
})
export class SisenseConfigService {
  constructor(private http: HttpClient, private errorService: ErrorService) {}

  getDashboardId(dashboardName: string): string {
    ...
  }

  getWidgetInfo(dashboardName: string, widgetName: string): ISisenseWidget {
   ...
   return widgetInfo;
  }
}

我已经编写了测试文件,但她不同意。请帮助我我的技术负责人到底要求什么。欢迎询问更多代码详情。

【问题讨论】:

  • 为什么要使用 for 循环而不是 forEach?
  • 好的。我会成功的forEach
  • 我会帮助你,但我在阅读 getDataFromWidget 函数时遇到了困难。我建议你上这门课,这太棒了,你会以一种很好的方式学习 Angular 单元测试。 app.pluralsight.com/library/courses/unit-testing-angular/…。创建免费试用版。
  • @AliF50,我只关注这个。我正在关注 Joe Eames 的 AAA 测试概念和 Deborah Kurata 的一些讲座。顺便说一句,我已经购买了 1 年的订阅。 :-)
  • @Tanzeel 看看我的回答,如果有帮助请告诉我/

标签: angular typescript unit-testing karma-jasmine angular-test


【解决方案1】:

这对你有帮助


describe('FilterPanelComponent', () => {
    let component: FilterBarComponent;
    let fixture: ComponentFixture<FilterBarComponent>;
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                FilterBarComponent
            ],
            imports: [],
            providers: [
                {
                    provide: SisenseService,
                    useClass: SisenseServiceStub
                },
                SisenseConfigService
            ]
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(FilterBarComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('should call getDataFromWidget() on init method',()=>{
        spyOn(component,'getDataFromWidget').and.callThrough();
        component.ngOnInit();
        expect(component.getDataFromWidget).toHaveBeenCalled()
    })

    it('getDataFromWidget should set selected member count',()=>{
        component.selectedMembersCount = 0;
        component.getDataFromWidget();
        expect(component.selectedMembersCount).toEqual(1);
        fixture.detectChanges();
        const htmlEle  = fixture.debugElement.nativeElement.querySelector('#some-count'); // For class try query(By.css('.some-count')).nativeElement;
        expect(htmlEle.innerHTML).toBe(1);        
    })
});

// this is the stub she is talking about
export class SisenseServiceStub{
    getWidgetData(){
        return of({
            queryResult : {
                value : {
                    data : 1
                }
            }
        })
    }
}

几个月前,我还看到我的一些小辈在单元测试中苦苦挣扎。所以,我写了series of articles which can help you as well

试一试,如果有帮助,请告诉我。 Here is how you play with stubs and spies

【讨论】:

  • 我可以等着试试这个。先生,我会回复您的。 :-)
  • @Tanzeel : 很酷,如果您还有其他问题,请告诉我
  • 先生,这对我来说已经足够了。从这里我可以控制。感谢您的文章。我会和我的实习生分享。 :-)
  • @Tanzeel : 很高兴为您提供帮助 :) 也请随时为您鼓掌 ;)
  • 先生,你能回答这个吗,stackoverflow.com/questions/61474540/…
猜你喜欢
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-01
  • 1970-01-01
  • 2021-03-03
  • 2016-06-29
相关资源
最近更新 更多