When I try to mock react-native-sound with Jest I get the following error:
//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"
}
}
Alternatively I've tried setting up a manual mock in a separated file (__mock__
folder) with similar luck:
//__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
Any guidance or advice will be greatly appreciated. Thanks much in advance!
Well, I found the problem in the end.
The way I was trying to make the mock was the problem, so what I did was to to return a new function simulating what I need to mock:
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;
});
You have to mock all of the functionality you are using. The mocks you made aren't providing all of the functionality you need. You need to mock the constructor for Sound because you are creating one, you need to mock Sound.LIBRARY because you are using that as well. Also, the mock you need to make is very simple I wouldn't bother using genMockFromModule it's more for extending the module. Just implement a simple mock yourself it will give you more control over what the module actually does. Since you are using babel and ES6 I would just mock this as a class and mock all of the functions you use.
Something like this. . .
// __mocks__/react-native-sound.js
class Sound {
constructor(path, type, callback) {
...
}
LIBRARY = 1
}
export Sound;
Then in your test
jest.mock('react-native-sound');
I'm not entirely sure on the syntax for replacing a module in react-native (just make sure your mocks folder is in the same directory as what you are including) so you might also need to specify that you are trying to replace the module in moduleNameMapper like this and then I don't believe you need to mock it in your file. However this will only work if you plan on mocking react-native-sound globally.
"moduleNameMapper": {
"react-native-sound": "<rootDir>/__mocks__/react-native-sound.js"
}
Now if you have any issues with something being undefined you can add it to your mock class and it will fix the issue.
Note that you can also use es5 syntax to do this if you prefer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With