Using enzyme 2.0.0, react-native-mock 0.0.6 and react-native 0.19.0
I have the following component:
import React, {
StyleSheet,
PropTypes,
View,
Text,
} from 'react-native';
export default class MyComponent extends React.Component {
constructor() {
super();
this.state = {text: 'INIT'}
}
componentDidMount() {
this.setState({text: 'I wonder if there will be any problems...'})
};
render() {
return (
<View>
<Text>{this.state.text}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {},
});
This is my spec (Mocha):
/* global React, shallow, mount, _, expect */
const {Text} = React;
import MyComponent from './MyComponent';
describe('<MyComponent />', () => {
it('should render stuff', () => {
const wrapper = shallow(<MyComponent />);
console.log(wrapper.debug());
expect(wrapper.length).to.equal(1);
expect(wrapper.contains(<Text>INIT</Text>)).to.equal(true);
});
it('componentDidMount updates text', () => {
const wrapper = shallow(<MyComponent />);
wrapper.instance().componentDidMount();
wrapper.update();
console.log(wrapper.debug());
expect(wrapper.contains(<Text>I wonder if there will be any problems...</Text>)).to.equal(true);
});
it('componentDidMount is called automatically when you call mount', () => {
const wrapper = mount(<MyComponent />);
console.log(wrapper.debug());
expect(wrapper.contains(<Text>I wonder if there will be any problems...</Text>)).to.equal(true);
});
});
The first two tests run without a problem.
For the third one I expected the mount call to execute componentDidMount of MyComponent right away.
Unfortunately it doesn't, debug() outputs the initial render output with "INIT". Is mount() not supported (yet) for React Native? Is the problem probably with the react native mock? Or do I something wrong here?
:+1: how is this supposed to work?
:thumbsup: How does it work the component lifecycle in ReactNative?
:+1: I seem to be having a similar issue even without React Native:
Component:
import React from 'react'
import request from 'superagent'
export default React.createClass({
getInitialState() {
return {cats: []}
},
componentDidMount() {
request('/api', (err, res) => {
if (err) return;
this.setState({
cats: res.body.results
})
})
},
render() {
let cats = this.state.cats
let catsList = (
<ul>
{cats.map((c) => <li key={c.id}>cat</li>)}
</ul>
)
return (
<div>
hello world
{cats.length ? catsList : null}
</div>
)
}
})
Test:
jest.unmock('../app.js')
jest.unmock('superagent')
import React from 'react'
import {mount} from 'enzyme'
import nock from 'nock'
import App from '../app.js'
describe('App', () => {
let ajaxFn
beforeEach(() => {
ajaxFn = nock('http://localhost')
.get('/api')
.reply(200, {
results: [{id: 1}, {id: 2}, {id: 3}]
})
})
it('says hello world', () => {
let wrapper = mount(<App/>)
expect(wrapper.text()).toContain('hello worl')
})
it('makes ajax request', () => {
let wrapper = mount(<App/>)
expect(ajaxFn.isDone()).toBe(true)
})
it('renders correct number of cats', () => {
let wrapper = mount(<App />)
expect(wrapper.state('cats').length).toBe(3)
})
})
The first 2 tests pass but the final one doesn't, i.e. wrapper.state('cats').length == 0
@ishanray request triggers an asynchronous action - won't that mean the setState call doesn't happen until the next tick?
@ljharb I tried with jest.runAllTicks() as well. That didn't work either.
@ishanray what does wrapper.state() print out?
@ljharb It prints out { cats: [] } before and after the mount call.
@ishanray and if you make the test async, and print that out in a setTimeout, before calling done?
@ljharb It still is the same.
I can not find an element while mount(<SomeComponent />) in react-native.
if I do:
const wrapper = mount(<SomeComponent />)
wrapper.find('TouchableOpacity').length
I get 0. This works when I shallow render (i.e. I get 1). I am using react-native-mock/mock.js to mock the react-native components.
Will show error TypeError: document.createElement is not a function, call mount() using enzyme 2.7.1 and jest on React Native
We made a fork of react-native-mock called react-native-mock-render that will render React Elements for Native components, which makes mount() work with jsdom. We wrote about it at https://blog.joinroot.com/mounting-react-native-components-with-enzyme-and-jsdom/
Any solution? I've tried https://github.com/airbnb/enzyme/issues/190#issuecomment-288153479
No luck so far:

hi @dan-manges
Thanks for your library but i'm working with Jest and according to this post it seems that it is not possible
Hi @jose920405! Unfortunately we use mocha and haven't tried to use react-native-mock-render with jest.
@jose920405 I'm using Jest + Enzyme + react-native-mock and can successfully create snapshots using shallow. Have not tried mount yet.
thanks @swl367
also got it working even without the need for mock-store. my problem was related to the beta and alpha versions of react
Now I am trying to solve an error with the react life cycles and trying to make the componentDidUpdate works.
If maybe you have something that you can help me with this problem, I would really appreciate it. This is the link.
https://github.com/airbnb/enzyme/pull/318#issuecomment-339696502
You'd need a react native adapter to use enzyme with React Native.
Closing this in favor of #1436.
Most helpful comment
Will show error
TypeError: document.createElement is not a function, callmount()using enzyme 2.7.1 and jest on React Native