Enzyme: mount() doesn't seem to work with React Native

Created on 15 Feb 2016  路  18Comments  路  Source: enzymejs/enzyme

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?

Most helpful comment

Will show error TypeError: document.createElement is not a function, call mount() using enzyme 2.7.1 and jest on React Native

All 18 comments

:+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:
image

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

potapovDim picture potapovDim  路  3Comments

aweary picture aweary  路  3Comments

dschinkel picture dschinkel  路  3Comments

blainekasten picture blainekasten  路  3Comments

amcmillan01 picture amcmillan01  路  3Comments