Skip to content

Instantly share code, notes, and snippets.

@jmreidy
Last active January 9, 2018 11:49
Show Gist options
  • Save jmreidy/4145809229195441d4d4 to your computer and use it in GitHub Desktop.
Save jmreidy/4145809229195441d4d4 to your computer and use it in GitHub Desktop.
Unit test React Native with Mocha
--compilers js:./test/support/compiler
--require ./test/support/init
/* eslint-env node, mocha */
import NoteEntryScreen from '../src/containers/screens/NoteEntryScreen';
import common from './support/common';
const {createRenderer, React, expect, MockComponents} = common;
function setup() {
const props = {};
const renderer = createRenderer();
renderer.render(<NoteEntryScreen {...props} />);
const output = renderer.getRenderOutput();
return {
props,
output,
renderer,
};
}
describe('NoteEntryScreen', () => {
it('should render a scrollview', () => {
const { output } = setup();
expect(output.type.displayName).to.equal(MockComponents.ScrollView.displayName);
});
});
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import {MockComponents} from './mocks/react-native';
chai.use(chaiAsPromised);
export default {
expect: chai.expect,
createRenderer: ReactTestUtils.createRenderer,
React,
MockComponents,
};
var fs = require('fs');
var path = require('path');
var babel = require('babel-core');
var origJs = require.extensions['.js'];
require.extensions['.js'] = function (module, fileName) {
var output;
if (fileName === '/app/node_modules/react-native/Libraries/react-native/react-native.js') {
fileName = path.resolve('./test/support/mocks/react-native.js');
}
if (fileName.indexOf('node_modules/') >= 0) {
return (origJs || require.extensions['.js'])(module, fileName);
}
var src = fs.readFileSync(fileName, 'utf8');
output = babel.transform(src, {
filename: fileName,
sourceFileName: fileName,
//keep below in sync with babelrc
"retainLines": true,
"compact": true,
"comments": false,
"plugins": [
"syntax-async-functions",
"syntax-class-properties",
"syntax-trailing-function-commas",
"transform-es2015-arrow-functions",
"transform-es2015-block-scoping",
"transform-es2015-classes",
"transform-es2015-computed-properties",
"transform-es2015-constants",
"transform-es2015-destructuring",
["transform-es2015-modules-commonjs", {"strict": false, "allowTopLevelThis": true}],
"transform-es2015-parameters",
"transform-es2015-shorthand-properties",
"transform-es2015-spread",
"transform-es2015-template-literals",
"transform-class-properties",
"transform-flow-strip-types",
"transform-object-assign",
"transform-object-rest-spread",
"transform-react-display-name",
"transform-react-jsx",
"transform-regenerator"
],
"sourceMaps": false
}).code;
return module._compile(output, fileName);
};
import React from 'react';
function mockComponent(type) {
const Component = React.createClass({
displayName: type,
propTypes: { children: React.PropTypes.node },
render() { return React.createElement(React.DOM.div, this.props, this.props.children); },
});
return Component;
}
const componentsToMock = [
'View',
'Text',
'Component',
'ScrollView',
'TextInput',
];
export const MockComponents = componentsToMock.reduce((agg, type) => {
agg[type] = mockComponent(type);
return agg;
}, {});
export default {
...React,
...MockComponents,
StyleSheet: {
create: (ss) => ss,
},
PropTypes: React.PropTypes,
};
@larubbio
Copy link

@miquelbeltran I had to modify the mock to get passed the TypeError

var ReactNative = {
  ...React,
  ...MockComponents,
  StyleSheet: {
    create: (ss) => ss,
  },
  PropTypes: React.PropTypes,
};

module.exports = ReactNative;

I think the error had to do with Component not being defined so when babel tried to transpile a module that extends it you get the error. We might be on a new version of some package that requires the different export syntax.

http://stackoverflow.com/questions/30116430/reactjs-giving-error-uncaught-typeerror-super-expression-must-either-be-null-or

I've also had to add mocks for at least one other module (react-native-router-flux) to get my tests to "run".

@sstur
Copy link

sstur commented Mar 2, 2016

I also got this working with some effort and modifications to the above files. Will post my solution...

@cornedor
Copy link

You could use the react-native preset so you won't have to keep the transforms in sync
https://gist.github.com/cornedor/37ab65a3a505797b01c2e78156d5cf12/revisions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment