typescript Angular - Mock new Audio()with Jasmine

x7yiwoj4  于 2023-04-22  发布在  TypeScript
关注(0)|答案(1)|浏览(131)

我有一个angular服务,它在特定条件下播放声音。我想模拟windowAudio类来监视play函数,以检查它是否被实际调用。
以下是我的班级:

import { Injectable } from "@angular/core";
import { SoundPreferencesStore } from "app/shared/stores/sound-preferences.store";

@Injectable({
    providedIn: "root"
})
export class Service {
    private readonly _audioPath: string = "assets/sounds/sound.mp3";
    private readonly _audio: HTMLAudioElement;

    public isSoundMuted: boolean;

    constructor(
        private readonly _soundPreferencesStore: SoundPreferencesStore
    ) {
        this._audio = new Audio(this._audioPath);
        this.isSoundMuted = this._soundPreferencesStore.isSoundMuted();
    }

    public playSound(): void {
        if (!this.isSoundMuted) {
            this._audio.play().catch(() => {});
        }
    }
}

我想模拟Audio类,以检查当我使用Jasmine在我的服务中调用playSound函数时,是否调用了play函数,如下所示:

describe("playSound", () => {
    it("should play sound", async () => {
        // Arrange
        // Here is where I would use the mock
        const audioMock = jasmine.createSpyObj<Audio>(["play"]);
        service.isSoundMuted = false;

        // Act
        service.playSound();

        // Assert
        expect(audioMock.play).toHaveBeenCalled();
    });
});

谢谢你的帮助

plicqrtu

plicqrtu1#

你可以尝试测试play()是否被调用,如果你想在服务中添加某种标志,你不能模拟一个类属性,你甚至不能从外部访问一个private属性,即使在测试服务本身。
也许有一个更好,更聪明的方法,但是,我会像下面这样测试它:

服务项目

@Injectable({...})
export class Service {
  ... 
  ...
  public playWasTriggered = false;
  
  ...

  public playSound(): void {
    if (!this.isSoundMuted) {
      this.playWasTriggered = true;
      this._audio.play().catch(() => {});
    } else this.playWasTriggered = false;
  }
}

规格

describe('Service', () => {
  let service: Service;
  const mockSoundService = jasmine.createSpyObj<SoundPreferencesStore>('SoundPreferencesStore', ['isSoundMuted']);

  // it will play a sound since it returns TRUE
  beforeEach(() => mockSoundService.isSoundMuted.and.returnValue(true))

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [{ provide: SoundPreferencesStore, useValue: mockSoundService }]
    });
    service = TestBed.inject(Service);
  });

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

  it('plays a sound', () => {
     component.playSound();
     expect(component.playWasTriggered).toBe(true);
  });
}

相关问题