欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在Angular測(cè)試中使用spy的教程詳解

 更新時(shí)間:2024年03月28日 11:33:30   作者:白如意i  
spy?是一種檢查函數(shù)是否被調(diào)用或提供自定義返回值的方法,我們可以使用spy?來測(cè)試依賴于服務(wù)的組件,并避免實(shí)際調(diào)用服務(wù)的方法來獲取值,在本文中,您將學(xué)習(xí)如何在?Angular?項(xiàng)目中使用?Jasmine?spy,需要的朋友可以參考下

簡(jiǎn)介

Jasmine spy 用于跟蹤或存根函數(shù)或方法。spy 是一種檢查函數(shù)是否被調(diào)用或提供自定義返回值的方法。我們可以使用spy 來測(cè)試依賴于服務(wù)的組件,并避免實(shí)際調(diào)用服務(wù)的方法來獲取值。這有助于保持我們的單元測(cè)試專注于測(cè)試組件本身的內(nèi)部而不是其依賴關(guān)系。

在本文中,您將學(xué)習(xí)如何在 Angular 項(xiàng)目中使用 Jasmine spy。

先決條件

要完成本教程,您需要:

  • 在本地安裝 Node.js
  • 一些關(guān)于設(shè)置 Angular 項(xiàng)目的基礎(chǔ)知識(shí)。

本教程已使用 Node v16.2.0、npm v7.15.1 和 @angular/core v12.0.4 進(jìn)行驗(yàn)證。

步驟 1 — 設(shè)置項(xiàng)目

讓我們使用一個(gè)與我們?cè)?Angular 單元測(cè)試介紹中使用的示例非常相似的示例。

首先,使用 @angular/cli 創(chuàng)建一個(gè)新項(xiàng)目:

ng new angular-test-spies-example

然后,切換到新創(chuàng)建的項(xiàng)目目錄:

cd angular-test-spies-example

以前,該應(yīng)用程序使用兩個(gè)按鈕在 0 到 15 之間增加和減少值。

對(duì)于本教程,邏輯將被移動(dòng)到一個(gè)服務(wù)中。這將允許多個(gè)組件訪問相同的中央值。

ng generate service increment-decrement

然后,打開您的代碼編輯器中的 increment-decrement.service.ts 并用以下代碼替換內(nèi)容:

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

@Injectable({
  providedIn: 'root'
})
export class IncrementDecrementService {
  value = 0;
  message!: string;

  increment() {
    if (this.value < 15) {
      this.value += 1;
      this.message = '';
    } else {
      this.message = 'Maximum reached!';
    }
  }

  decrement() {
    if (this.value > 0) {
      this.value -= 1;
      this.message = '';
    } else {
      this.message = 'Minimum reached!';
    }
  }
}

打開您的代碼編輯器中的 app.component.ts 并用以下代碼替換內(nèi)容:

import { Component } from '@angular/core';
import { IncrementDecrementService } from './increment-decrement.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(public incrementDecrement: IncrementDecrementService) { }

  increment() {
    this.incrementDecrement.increment();
  }

  decrement() {
    this.incrementDecrement.decrement();
  }
}

打開您的代碼編輯器中的 app.component.html 并用以下代碼替換內(nèi)容:

<h1>{{ incrementDecrement.value }}</h1>

<hr>

<button (click)="increment()" class="increment">Increment</button>

<button (click)="decrement()" class="decrement">Decrement</button>

<p class="message">
  {{ incrementDecrement.message }}
</p>

接下來,打開您的代碼編輯器中的 app.component.spec.ts 并修改以下代碼行:

import { TestBed, waitForAsync, ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';

import { AppComponent } from './app.component';
import { IncrementDecrementService } from './increment-decrement.service';

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let debugElement: DebugElement;
  let incrementDecrementService: IncrementDecrementService;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      providers: [ IncrementDecrementService ]
    }).compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    debugElement = fixture.debugElement;

    incrementDecrementService = debugElement.injector.get(IncrementDecrementService);
  }));

  it('should increment in template', () => {
    debugElement
      .query(By.css('button.increment'))
      .triggerEventHandler('click', null);

    fixture.detectChanges();

    const value = debugElement.query(By.css('h1')).nativeElement.innerText;

    expect(value).toEqual('1');
  });

  it('should stop at 15 and show maximum message', () => {
    incrementDecrementService.value = 15;
    debugElement
      .query(By.css('button.increment'))
      .triggerEventHandler('click', null);

    fixture.detectChanges();

    const value = debugElement.query(By.css('h1')).nativeElement.innerText;
    const message = debugElement.query(By.css('p.message')).nativeElement.innerText;

    expect(value).toEqual('15');
    expect(message).toContain('Maximum');
  });
});

請(qǐng)注意,我們可以使用 debugElement.injector.get 獲取對(duì)注入服務(wù)的引用。

以這種方式測(cè)試我們的組件是有效的,但實(shí)際調(diào)用也將被傳遞到服務(wù),并且我們的組件沒有被孤立測(cè)試。接下來,我們將探討如何使用 spy 來檢查方法是否已被調(diào)用或提供存根返回值。

步驟 2 —— 監(jiān)視服務(wù)的方法

以下是如何使用 Jasmine 的 spyOn 函數(shù)調(diào)用一個(gè)服務(wù)方法并測(cè)試它是否被調(diào)用:

import { TestBed, waitForAsync, ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';

import { AppComponent } from './app.component';
import { IncrementDecrementService } from './increment-decrement.service';

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let debugElement: DebugElement;
  let incrementDecrementService: IncrementDecrementService;
  let incrementSpy: any;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      providers: [ IncrementDecrementService ]
    }).compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    debugElement = fixture.debugElement;

    incrementDecrementService = debugElement.injector.get(IncrementDecrementService);
    incrementSpy = spyOn(incrementDecrementService, 'increment').and.callThrough();
  }));

  it('should call increment on the service', () => {
    debugElement
      .query(By.css('button.increment'))
      .triggerEventHandler('click', null);

    expect(incrementDecrementService.value).toBe(1);
    expect(incrementSpy).toHaveBeenCalled();
  });
});

spyOn 接受兩個(gè)參數(shù):類實(shí)例(在本例中是我們的服務(wù)實(shí)例)和一個(gè)字符串值,表示要監(jiān)視的方法或函數(shù)的名稱。

在這里,我們還在 spy 上鏈接了 .and.callThrough(),這樣實(shí)際方法仍然會(huì)被調(diào)用。在這種情況下,我們的 spy 只用于判斷方法是否被調(diào)用以及監(jiān)視參數(shù)。

以下是斷言方法被調(diào)用兩次的示例:

expect(incrementSpy).toHaveBeenCalledTimes(2);

以下是斷言方法未被使用 'error' 參數(shù)調(diào)用的示例:

expect(incrementSpy).not.toHaveBeenCalledWith('error');

如果我們想避免實(shí)際調(diào)用服務(wù)上的方法,可以在 spy 上使用 .and.returnValue。

我們的示例方法不適合這樣做,因?yàn)樗鼈儾环祷厝魏蝺?nèi)容,而是改變內(nèi)部屬性。

讓我們向服務(wù)添加一個(gè)實(shí)際返回值的新方法:

minimumOrMaximumReached() {
  return !!(this.message && this.message.length);
}

我們還向組件添加一個(gè)新方法,模板將使用它來獲取值:

limitReached() {
  return this.incrementDecrement.minimumOrMaximumReached();
}

然后,我們可以測(cè)試當(dāng)達(dá)到限制時(shí),我們的模板消息是否會(huì)顯示,而無需實(shí)際調(diào)用服務(wù)上的方法:

import { TestBed, waitForAsync, ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';

import { AppComponent } from './app.component';
import { IncrementDecrementService } from './increment-decrement.service';

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let debugElement: DebugElement;
  let incrementDecrementService: IncrementDecrementService;
  let minimumOrMaximumSpy: any;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      providers: [ IncrementDecrementService ]
    }).compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    debugElement = fixture.debugElement;

    incrementDecrementService = debugElement.injector.get(IncrementDecrementService);
    minimumOrMaximumSpy = spyOn(incrementDecrementService, 'minimumOrMaximumReached').and.returnValue(true);
  }));

  it(`should show 'Limit reached' message`, () => {
    fixture.detectChanges();

    const message = debugElement.query(By.css('p.message')).nativeElement.innerText;

    expect(message).toEqual('Limit reached!');
  });
});

結(jié)論

在本文中,您學(xué)習(xí)了如何在 Angular 項(xiàng)目中使用 Jasmine spy。

到此這篇關(guān)于在Angular測(cè)試中使用spy的教程詳解的文章就介紹到這了,更多相關(guān)Angular中使用spy內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • AngularJS實(shí)現(xiàn)的生成隨機(jī)數(shù)與猜數(shù)字大小功能示例

    AngularJS實(shí)現(xiàn)的生成隨機(jī)數(shù)與猜數(shù)字大小功能示例

    這篇文章主要介紹了AngularJS實(shí)現(xiàn)的生成隨機(jī)數(shù)與猜數(shù)字大小功能,結(jié)合完整實(shí)例形式分析了AngularJS隨機(jī)數(shù)生成與數(shù)值判定相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • AngularJS ng-change 指令的詳解及簡(jiǎn)單實(shí)例

    AngularJS ng-change 指令的詳解及簡(jiǎn)單實(shí)例

    本文主要介紹AngularJS ng-change 指令,這里對(duì)ng-change指令資料做了詳細(xì)介紹,并提供源碼和運(yùn)行結(jié)果,有需要的小伙伴參考下
    2016-07-07
  • AngularJS自定義插件實(shí)現(xiàn)網(wǎng)站用戶引導(dǎo)功能示例

    AngularJS自定義插件實(shí)現(xiàn)網(wǎng)站用戶引導(dǎo)功能示例

    這篇文章主要介紹了AngularJS自定義插件實(shí)現(xiàn)網(wǎng)站用戶引導(dǎo)功能,結(jié)合實(shí)例形式分析了AngularJS自定義插件的實(shí)現(xiàn)步驟與相關(guān)功能技巧,需要的朋友可以參考下
    2016-11-11
  • Angular設(shè)置別名alias的方法

    Angular設(shè)置別名alias的方法

    這篇文章主要介紹了Angular設(shè)置別名alias及打包命令的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-11-11
  • 最新評(píng)論