Насмешливый конструктор обратного вызова - PullRequest
0 голосов
/ 08 января 2019

Я пишу юнит-тесты для класса AudioPlayer, который использует реагировать-родной-звук , поэтому я пытаюсь смоделировать react-native-sound, используя ручной макет в папке __mocks__. Вот высмеянный класс:

export default class Sound {
  _filename = null;
  _basePath = null;
  _duration = -1;
  _currentTime = 0;
  _volume = 1;
  _loaded = false;

  constructor(filename, basePath, callback) {
    this._filename = filename;
    this._basePath = basePath;
    this._duration = 500;
    this._loaded = true;

    callback();
  }

  static setCategory = (value, mixWithOthers) => {};
  static setMode = value => {};
  static setActive = value => {};

  isLoaded = () => { return this._loaded; };
  getDuration = () =>  { return this._duration; };
  getCurrentTime = callback => {
    callback(this._currentTime);
  };
  getVolume = () => { return this._volume; };
  setVolume = value => {
    this._volume = value;
  };
}

Класс AudioPlayer имеет метод загрузки с необязательным параметром для тома, например:

export default class AudioPlayer {
  loaded = false;
  load = (path: string, volume: number = 1) => {
    const that = this;
    return new Promise((resolve, reject) => {
      const sound = new Sound(path, "", error => {
        if (error) {
          reject(error);
        } else {
          sound.setVolume(volume); // <----- Fail here
          loaded = true;
          resolve();
        }
      });
    });
  };

И вот что я пытаюсь в модульном тесте:

jest.mock("react-native-sound");

describe("audio-player", () => {
  it("can load audio file", () => {
    expect.assertions(1);
    const audioPlayer = new AudioPlayer();
    const path = "sample_audio.mp3";
    return audioPlayer.load(path).then(() => {
      expect(audioPlayer.loaded).toEqual(true);
    });
  });
});

Но, это не так со следующим сообщением об ошибке:

TypeError: Невозможно прочитать свойство 'setVolume' из неопределенного

И это потому, что код, который пытается установить объем, находится внутри конструктора, и по какой-то причине макетируемый класс все еще не определен внутри конструктора. Как мне заставить это работать? Как я могу сделать конструктор с функцией обратного вызова?

1 Ответ

0 голосов
/ 08 января 2019

Я понял это. Я просто поместил вызов функции обратного вызова внутри конструктора в течение 2000 миллисекунд:

constructor(filename, basePath, callback) {
    this._filename = filename;
    this._basePath = basePath;
    this._duration = 500;
    this._loaded = true;

    setTimeout(() => {
        callback();
    }, 2000);
}
...