模拟构造函数回调

时间:2019-01-08 00:08:05

标签: unit-testing react-native mocking jestjs

我正在为使用react-native-sound的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 :(得分:0)

我知道了。我只是在2000毫秒的超时时间内将对回调函数的调用放在了构造函数中:

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

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