react-native-mock
react-native-mock copied to clipboard
Issues with mocking interfering with 3rd-party node modules
I'm having some issues getting a basic test to compile. I'm fairly new to React Native / Mocha / Babel so any insight would be helpful.
I followed your advice regarding forcing babel to compile node modules here, with some modifications of my own due to some problematic modules. However, now the issue seems to be that there is a conflict between react-native-mock getting in the way of an external node module ("react-native-router-flux" in this case) from functioning properly.
Any thoughts would be greatly appreciated!
/* .babelrc */
{
"presets": ["stage-1", "react-native"]
}
/* MyComponent.js */
'use strict';
var React = require('react-native');
var {View, Text, StyleSheet, TouchableHighlight} = React;
var Button = require('react-native-button');
var Actions = require('react-native-router-flux').Actions;
class MyComponent extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.baseText}>Test!</Text>
<Button onPress={()=>Actions.login({data:"Custom data", title:'Custom title' })}>Go to Login page</Button>
<Button onPress={Actions.signup}>Go to Register page</Button>
</View>
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'transparent',
},
baseText: {
fontFamily: 'Raleway-Regular'
}
});
module.exports = MyComponent;
/* MyComponent_spec.js */
import React from 'react';
import { shallow } from 'enzyme';
import { View, Text, StyleSheet } from 'react-native';
import MyComponent from '../../../react/components/ecosystems/MyComponent';
describe("<MyComponent/>", () => {
it('should render', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper).to.be.ok;
});
});
/* package.json */
{
"name": "Test",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "mocha --require ./test/setup.js --compilers js:babel-core/register 'test/**/*.@(js|jsx)'"
},
"dependencies": {
"immutable": "^3.7.6",
"react-native": "^0.21.0",
"react-native-button": "^1.4.2",
"react-native-router-flux": "^2.3.12",
"react-redux": "^4.4.0",
"redux": "^3.3.1"
},
"devDependencies": {
"babel-cli": "^6.6.5",
"babel-core": "^6.7.2",
"babel-plugin-transform-es2015-modules-commonjs": "^6.7.0",
"babel-polyfill": "^6.7.2",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-preset-react-native": "^1.5.2",
"babel-preset-stage-1": "^6.5.0",
"chai": "^3.5.0",
"chai-immutable": "^1.5.3",
"enzyme": "^2.1.0",
"mocha": "^2.4.5",
"react": "^0.14.7",
"react-addons-test-utils": "^0.14.7",
"react-dom": "^0.14.7",
"react-native-mock": "0.0.6",
"redux-devtools": "^3.1.1",
"sinon": "^1.17.3",
"slash": "^1.0.0"
}
}
/* ./test/setup.js */
"use strict";
require("babel-polyfill");
var fs = require('fs');
var path = require('path');
function getBabelRC() {
var rcpath = path.join(__dirname, '..', '.babelrc');
var source = fs.readFileSync(rcpath).toString();
return JSON.parse(source);
}
var config = getBabelRC();
config.ignore = function(filename) {
if (!(/\/node_modules\//).test(filename)) {
// if not in node_modules, we want to compile it
return false;
} else if ((/\/node_modules\/react-native\//).test(filename)) {
// it's RN source code, so we want to compile it
return false;
} else {
// it's in node modules and NOT RN source code
var modulesToCompileArray = [
"react-native-button",
"react-native-router-flux",
"react-native-tabs",
"exponent",
"react-native-clone-referenced-element",
];
for (var i = 0; i < modulesToCompileArray.length; i++) {
if (filename.includes(modulesToCompileArray[i])) {
return false;
}
}
return true;
}
}
require("babel-core/register")(config);
global.__DEV__ = true;
var chai = require('chai');
var chaiImmutable = require('chai-immutable');
global.expect = chai.expect;
chai.use(chaiImmutable);
require("react-native-mock/mock");
This is the error that I get when running the tests.
npm run test
> [email protected] test .../src...
> mocha --require ./test/setup.js --compilers js:babel-core/register 'test/**/*.@(js|jsx)'
.../src.../node_modules/@exponent/react-native-navigator/ExSceneConfigs.js:193
Fade:_reactNative.Navigator.SceneConfigs.FadeAndroid,
^
TypeError: Cannot read property 'FadeAndroid' of undefined
at Object.<anonymous> (ExSceneConfigs.js:193:9)
at Module._compile (module.js:413:34)
at loader (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (ExRouteRenderer.js:16:1)
at Module._compile (module.js:413:34)
at loader (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (ExNavigator.js:16:1)
at Module._compile (module.js:413:34)
at loader (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (ExRouter.js:5:1)
at Module._compile (module.js:413:34)
at loader (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (Router.js:12:1)
at Module._compile (module.js:413:34)
at loader (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (index.js:4:1)
at Module._compile (module.js:413:34)
at loader (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (Welcome.js:6:15)
at Module._compile (module.js:413:34)
at loader (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (Welcome_spec.js:5:1)
at Module._compile (module.js:413:34)
at loader (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (.../src.../node_modules/babel-core/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at .../src.../node_modules/mocha/lib/mocha.js:219:27
at Array.forEach (native)
at Mocha.loadFiles (.../src.../node_modules/mocha/lib/mocha.js:216:14)
at Mocha.run (.../src.../node_modules/mocha/lib/mocha.js:468:10)
at Object.<anonymous> (.../src.../node_modules/mocha/bin/_mocha:403:18)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:141:18)
at node.js:933:3
npm ERR! Darwin 15.3.0
npm ERR! argv "/Users/noobs/.nvm/versions/node/v5.7.1/bin/node" "/Users/noobs/.nvm/versions/node/v5.7.1/bin/npm" "run" "test"
npm ERR! node v5.7.1
npm ERR! npm v3.6.0
npm ERR! code ELIFECYCLE
npm ERR! [email protected] test: `mocha --require ./test/setup.js --compilers js:babel-core/register 'test/**/*.@(js|jsx)'`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] test script 'mocha --require ./test/setup.js --compilers js:babel-core/register 'test/**/*.@(js|jsx)''.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the TestApp package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! mocha --require ./test/setup.js --compilers js:babel-core/register 'test/**/*.@(js|jsx)'
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs TestApp
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls TestApp
npm ERR! There is likely additional logging output above.
npm ERR! Please include the following file with any support request:
npm ERR! .../src.../npm-debug.log
Also, worth noting that a simple test on a component with no 3rd party node modules passes, if it's the only test running in the suite.
/* TestComponent_spec.js */
import React from 'react';
import { shallow } from 'enzyme';
import { View, Text, StyleSheet } from 'react-native';
import TestComponent from '../../../react/components/atoms/TestComponent'
describe("<TestComponent/>", () => {
it('should be ok', () => {
expect(true).to.be.ok;
});
it('should render stuff', () => {
const wrapper = shallow(<TestComponent />);
expect(wrapper.length).to.equal(1);
expect(wrapper.contains(<Text>I wonder if there will be any problems...</Text>)).to.equal(true);
});
});
/* TestComponent.js */
import React from "react-native";
const {
View,
Text
} = React;
export default class TestComponent extends React.Component {
render() {
return (
<View>
<Text>I wonder if there will be any problems...</Text>
</View>
);
}
}
@rlau1115 I'm wondering if you found a fix or work around, facing the same issue :disappointed:
Unfortunately no :( Had to skip testing since I was under the gun for a release.
@rlau1115 Ah! :( thank you for the quick reply :smiley:
@rlau1115 @vysakh0 I feel that it's most RN wannabe-testers destiny... :(
+1
@rlau1115 Looks like some kind of problem in the code of exponent. The mock for navigator exposes that scene config properly. Whilst trying to use react-native-router-flux, I gave up trying to get it to work and just used Mockery to write a custom mock for that module.
@sattaman Is this still happening with the most recent version?
hey @RealOrangeOne can u provide an example or snippet of using Mockery to handle react-native-router-flux?
@sibeliusseraphini Unfortunately the code I used is closed source by my company. I think that's more an issue for the react-native-router-flux repo, as it doesnt affect react-native-mock
this is my testHelper.js
require('babel-polyfill');
require('react-native-mock/mock');
// require('babel-core/register')({
// ignore: function(packageName) {
// if (packageName.match(/node_modules/)) {
// return !(packageName.match(/react-native-vector-icons/)
// || packageName.match(/react-native-animatable/)
// || packageName.match(/react-native-router-flux/)
// || packageName.match(/react-native-tab-navigator/)
// );
// }
// return false;
// }
// });
var fs = require('fs');
var path = require('path');
function getBabelRC() {
var rcpath = path.join(__dirname, '.babelrc');
var source = fs.readFileSync(rcpath).toString();
return JSON.parse(source);
}
var config = getBabelRC();
config.ignore = function(filename) {
if (!(/\/node_modules\//).test(filename)) {
console.log(filename, 'FALSE');
return false; // if not in node_modules, we want to compile it
} else if ((/\/node_modules\/react-native.*\//).test(filename)) {
// its RN source code, so we want to compile it
console.log(filename, 'FALSE');
return false;
} else {
console.log(filename, 'TRUE');
// it's in node modules and NOT RN source code
return true;
}
};
require("babel-register")(config);
global.__DEV__ = true;
// var chai = require('chai');
// var dirtyChai = require('dirty-chai');
// chai.use(dirtyChai);
import chai from 'chai';
import dirtyChai from 'dirty-chai';
// import chaiImmutable from 'chai-immutable';
chai.use(dirtyChai);
//chai.use(chaiImmutable);
import mockery from "mockery";
mockery.enable();
mockery.registerMock('./node_modules/react-native-router-flux/src/menu_burger.png', 0);
and this is my npm test
"test": "node_modules/.bin/mocha --compilers js:babel-core/register --require testHelper.js **/__test__/*.js",
Maybe this could help @rlau1115 @vysakh0
only the image part is not working properly
Youre not setting up mockery correctly, the path is the path it imports not the path to the file. Please see mockery docs
How can I add some custom mock for some custom library like https://github.com/luggg/react-native-config?
Using mockery http://stackoverflow.com/a/37655424/168012
config.ignore function suggested by @sibelius worked for me - was having issues with spread operator in a 3rd party module