Hi, I have been struggling to properly test react-native components, so I resigned to mount them and I am currently testing them only on shallow or render methods. I opened a stackoverflow question in case someone can help in this matter.
However on every test I get a long list of warnings (printed with console.error, but not crashing the test), about the properties that are expected / received:
Ran all test suites matching "app/components/__tests__/components-test.js".
console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
Warning: In next release empty section headers will be rendered. In this release you can use 'enableEmptySections' flag to render empty section headers.
console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
Warning: Unknown props `refreshControl`, `renderRow`, `renderHeader`, `renderFooter`, `dataSource`, `initialListSize`, `pageSize`, `scrollRenderAheadDistance`, `onEndReachedThreshold`, `stickyHeaderIndices`, `scrollEventThrottle`, `removeClippedSubviews`, `onKeyboardWillShow`, `onKeyboardWillHide`, `onKeyboardDidShow`, `onKeyboardDidHide`, `onContentSizeChange`, `onLayout` on <ScrollView> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop
in ScrollView (created by ScrollView)
in ScrollView (created by ListView)
in ListView (created by DynGridLayout)
in DynGridLayout
in Provider
I would like to remove such warnings or have a resource I can follow to properly test react-native components on Jest
I think you can not use render to react-native components, see https://github.com/airbnb/enzyme/blob/master/docs/guides/react-native.md
With shallow it does not prompt warnings, and it does work with render (so tests are working). However they cannot yet be used with mount (I believe) because of the Native DOM.
It would be great –even if a workaround– to remove such logs.
Even with shallow() I have one warning:
console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
Warning: ReactTestUtils has been moved to react-dom/test-utils. Update references to remove this warning.
Why would I need react-dom when I use react-native?
edit: even after installing react-dom it gives the same warning
I also had the same issue with shallow().
I cloned https://github.com/Microsoft/TypeScript-React-Native-Starter and upgraded all dev packages.
I then did the setup for React 16:
import * as enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
enzyme.configure({
adapter: new Adapter(),
});
And ran jest with the simple test that came with the repo.
import * as React from 'react';
import { Text } from 'react-native';
import { shallow } from 'enzyme';
import Hello from '../Hello';
it('renders correctly with defaults', () => {
const hello = shallow(<Hello name="World" />);
expect(hello.find(Text).render().text()).toEqual("Hello World!");
});
Which is testing this simple React Native component using only very basic React Native components:
https://github.com/Microsoft/TypeScript-React-Native-Starter/blob/master/src/components/Hello.tsx
return (
<View style={styles.root}>
<Text style={styles.greeting}>
Hello {name + getExclamationMarks(enthusiasmLevel)}
</Text>
<View style={styles.buttons}>
<View style={styles.button}>
<Button title="-" onPress={onDecrement || (() => {})} color='red' />
</View>
<View style={styles.button}>
<Button title="+" onPress={onIncrement || (() => {})} color='blue' />
</View>
</View>
</View>
);
And I got the following warnings:
PASS src/components/__tests__/Hello.tsx
✓ renders correctly with defaults (33ms)
console.error node_modules/fbjs/lib/warning.js:33
Warning: <Text /> is using uppercase HTML. Always use lowercase HTML tags in React.
console.error node_modules/fbjs/lib/warning.js:33
Warning: Received `true` for a non-boolean attribute `accessible`.
If you want to write it to the DOM, pass a string instead: accessible="true" or accessible={value.toString()}.
in Text
in Text
console.error node_modules/fbjs/lib/warning.js:33
Warning: React does not recognize the `allowFontScaling` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `allowfontscaling` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
in Text
in Text
console.error node_modules/fbjs/lib/warning.js:33
Warning: React does not recognize the `ellipsizeMode` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `ellipsizemode` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
in Text
in Text
React 16 is for React web - to properly use enzyme with react-native, we'd need an enzyme-adapter-react-native.
@ljharb I'm interested in what would be required to make an enzyme-adapter-react-native. Is there anywhere where I can see documentation for implementing an adapter, or is just working off of the base react adapters the best?
Also, is there any effort to write the adapter already? I'd be curious of any information/insight you could give into seeing how a react-native adapter would work.
The best right now is to work off the base adapters.
I'm not aware of any current effort to write a react-native adapter.
Honestly F** it I did this for now to stop all the red in my console. I will watch #1436
describe('mounting', () => {
const origConsole = console.error;
beforeEach(() => {
console.error = () => {};
});
afterEach(() => {
console.error = origConsole;
});
it ......
mount....
});
@rmnegatives that will silence propType warnings, which should be failing your tests.
@ljharb yes it will, it is up to the developer to do due diligence check the warnings first, then fix the propType or any none 'DOM' type error. After things look good you can put in this temporary fix.
This should be fixed...
Did anyone figure out how to do @rmnegatives hack with the new Jest 22 globalSetup hook so it doesn't have to be repeated in every file?
For example, I tried to put this in the global setup file and it runs, but doesn't suppress the issues.
module.exports = async () => {
console.error = () => {}
}
You'd need a react native adapter to use enzyme with React Native.
Closing this in favor of #1436.
In Enzyme documentation, when creating setUp for Jest, add the following lines to the file:
const originalConsoleError = console.error;
console.error = (message) => {
if (message.startsWith('Warning:')) {
return;
}
originalConsoleError(message);
};
See full setUp file here: https://airbnb.io/enzyme/docs/guides/react-native.html#example-configuration-for-jest
I know this issue is closed, but my searching landed me here, so I'll post this here for others who might also end up here.
I took this a bit further in my TypeScript + React-Native + Redux + Jest + Enzyme + Enzyme Adapter app in order to filter out the Warning: Unknown props ... messages and also the react-native-i18n module is not correctly linked messages. Below is my entire, working, enzyme.ts setup file.
Hopefully, this is helpful until a more concrete and official solution is available.
Also available as a Gist for sharing around.
import 'react-native';
import 'jest-enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Enzyme from 'enzyme';
import { global } from 'core-js';
import { JSDOM } from 'jsdom';
const jsdom = new JSDOM();
const { window } = jsdom;
function copyProps(src: any, target: any) {
Object.defineProperties(target, {
...Object.getOwnPropertyDescriptors(src),
...Object.getOwnPropertyDescriptors(target),
});
}
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: 'node.js',
};
copyProps(window, global);
function _getCallerFile() {
const originalFunc = Error.prepareStackTrace;
let callerFile: string = 'unknown';
try {
const err = new Error();
let currentFile: string;
let stack: NodeJS.CallSite[];
let stackRecord: NodeJS.CallSite | undefined;
Error.prepareStackTrace = function(err, stack) {
return stack;
};
stack = <NodeJS.CallSite[]>(<unknown>err.stack);
stackRecord = <NodeJS.CallSite>stack.shift();
currentFile = stackRecord.getFileName() || '';
while (stack.length) {
stackRecord = <NodeJS.CallSite>stack.shift();
callerFile = stackRecord.getFileName() || '';
if (currentFile !== callerFile) break;
}
} catch (e) {
} finally {
Error.prepareStackTrace = originalFunc;
}
return callerFile;
}
function filteredConsole(
original: (message?: any, ...optionalParams: any[]) => void,
message?: any,
...optionalParams: any[]
) {
const callerFile = _getCallerFile();
const blockPattern = /.*(react-dom.development.js|module is not correctly linked)/i;
if (!blockPattern.test(callerFile) && !blockPattern.test(message)) {
original(message, ...optionalParams);
}
}
const originalConsoleWarn = console.warn;
const originalConsoleError = console.error;
console.error = (message?: any, ...optionalParams: any[]) =>
filteredConsole(originalConsoleError, message, ...optionalParams);
console.warn = (message?: any, ...optionalParams: any[]) =>
filteredConsole(originalConsoleWarn, message, ...optionalParams);
Enzyme.configure({ adapter: new Adapter() });
Honestly F** it I did this for now to stop all the red in my console. I will watch #1436
describe('mounting', () => { const origConsole = console.error; beforeEach(() => { console.error = () => {}; }); afterEach(() => { console.error = origConsole; }); it ...... mount.... });
A simple workaround to includes certain errors that we would like to log.
Still a temporary solution, but it works for me:
const origConsole = console.error;
const ALLOWED_ERROR_TAGS = ['failed prop type']
beforeEach(() => {
console.error = e => {
for(let tag of ALLOWED_ERROR_TAGS){
if (e.toLowerCase().includes(tag.toLowerCase())) {
console.warn(e);
break
}
}
};
});
afterEach(() => {
console.error = origConsole;
});
Hey guys, I found a tricky solution.
if you add to your test command both --verbose --silent it will remove all errors logs and keeps the checklist for each it.
worked well to me.

Same issue. Any solution ?
Most helpful comment
Honestly F** it I did this for now to stop all the red in my console. I will watch #1436