不能用Jest模仿反应原生声音

时间:2017-11-22 03:45:54

标签: reactjs unit-testing react-native mocking jestjs

当我尝试使用Jest模拟react-native-sound时,我收到以下错误:

//PlayerService.js
import Sound from 'react-native-sound';

try {
  console.log('Sound: ' + JSON.stringify(Sound)); //Sound: {}
  _trackPlaying = new Sound('path', Sound.LIBRARY, error => { });
} catch (error) {
  console.log('error: ' + JSON.stringify(error)); //error: {}
}
//PlayerService.tests.js
jest.mock('react-native-sound', () => ({
  Sound: jest.fn((path, type, callback) => {

  })
}));

// package.json

{
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-jest": "^21.2.0",
    "babel-plugin-transform-flow-strip-types": "^6.22.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-flow": "^6.23.0",
    "flow": "^0.2.3",
    "jest": "^21.2.1"
  },
  "jest": {
    "modulePathIgnorePatterns": [
      "__mocks__/"
    ]
  },
  "dependencies": {
    "react-native-sound": "^0.10.4"
  }
}

另外,我尝试在分离的文件(__mock__文件夹)中设置手动模拟,运气相似:

//__mocks__/react-native-sound.js
const Sound = jest.genMockFromModule('react-native-sound');

Sound = (path, type, callback) => {
  console.log("mocked");
}

module.exports = Sound;

//__tests__/PlayerService.tests.js
jest.mock('react-native-sound'); // doesn't work

我们将非常感谢任何指导或建议。非常感谢!

2 个答案:

答案 0 :(得分:1)

您必须模拟您正在使用的所有功能。您制作的模拟不提供您需要的所有功能。您需要模拟Sound的构造函数,因为您正在创建一个,您需要模拟Sound.LIBRARY,因为您也使用它。此外,您需要制作的模拟非常简单我不会使用genMockFromModule,它更多的是扩展模块。只需实现一个简单的模拟,它将使您更好地控制模块实际执行的操作。由于你使用的是babel和ES6,我只是将它作为一个类进行模拟并模拟你使用的所有函数。

像这样的东西。 。

// __mocks__/react-native-sound.js

class Sound {
  constructor(path, type, callback) {
    ...
  }

  LIBRARY = 1
}

export Sound;

然后在你的测试中

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

我不完全确定在react-native中替换模块的语法(只需确保 mocks 文件夹与您所包含的目录位于同一目录中),这样您可能还需要指定你试图像这样替换moduleNameMapper中的模块,然后我不认为你需要在你的文件中模拟它。但是,只有在您计划全局模拟反应原生声音时,这才有效。

"moduleNameMapper": {
  "react-native-sound": "<rootDir>/__mocks__/react-native-sound.js"
}

现在,如果您对未定义的内容有任何疑问,可以将其添加到您的模拟类中,它将解决问题。

请注意,如果您愿意,也可以使用es5语法执行此操作。

答案 1 :(得分:1)

好吧,我最终发现了这个问题。

我试图制作模拟的方式是问题,所以我做的是返回一个模拟我需要模拟的新函数:

jest.mock('react-native-sound', () => {
  var _filename = null;
  var _basePath = null;

  var SoundMocked = (filename, basePath, onError, options) => {
    _filename = filename;
    _basePath = basePath;
    onError();
  }

  SoundMocked.prototype.filename = () => _filename;
  SoundMocked.prototype.basePath = () => _basePath;
  SoundMocked.prototype.play = function (onEnd) { };
  SoundMocked.prototype.pause = function (callback) { };
  SoundMocked.prototype.stop = function (callback) { };
  SoundMocked.prototype.reset = function () { };
  SoundMocked.prototype.release = function () { };
  SoundMocked.prototype.getDuration = function () { };

  SoundMocked.LIBRARY = 2;

  return SoundMocked;
});
相关问题