How can I test react-native component with mocha +

2019-06-10 01:59发布

问题:

I'm using mocha, enzyme, chai and some mocking libraries to make the testing possible. So, the content of TestComponent.js is below, I configure the store and pass it to the provider, while DeskScreen is connected component:

import mockery from "mockery";
import 'babel-polyfill';
import reactNativeSvgMock from "react-native-svg-mock";
mockery.enable();
mockery.registerMock("react-native-svg", reactNativeSvgMock);
var DeskScreen = require( '../app/containers/DeskScreen/DeskScreen');
import React, {View, Text, StyleSheet} from 'react-native';
import {Provider} from 'react-redux';
import {shallow, render, mount} from 'enzyme';
import {expect} from 'chai';
import configureStore from 'redux-mock-store';
import reducer from "../app/reducers";
import Button from "../app/containers/Common/Button";
import ButtonWithNoFlex from "../app/containers/Common/ButtonWithNoFlex";
const mockStore = configureStore([]);

describe('<Test />', () => {
    it('it should render 1 view component', () => {
        const store = mockStore(reducer);
        var comp = shallow(
         <Provider store={store}>
            <DeskScreen/>
        </Provider>
    );
        expect(button).to.have.length(1);
        expect(comp.find(View)).to.have.length(1);
    });
});

After running the command npm test it produces the following:

1) it should render 1 view component


  0 passing (1s)
  1 failing

  1) <Test /> it should render 1 view component:
     AssertionError: expected { Object (root, unrendered, ...) } to have a length of 1 but got 0
      at Context.<anonymous> (test/TestComponent.js:22:41)

Maybe the reason is I use the shallow instead of mount, but as I know mount is not available for react-native. Anyway, I'd like to test connected component somehow.

回答1:

I think there are two ways to use solve the problem.

1. Export plain component

In your component file export the component as named export which you can use in your tests.

// Export the plain component as named component
export class MyComponent {
    // ...
}

export default connect(mapStateToProps)(MyComponent);

Your test import the plain compenent via named import:

import { MyComponent } from './MyComponent';

// Use it in your tests

2. Provide context via shallow

You can use the connected component if you provide the store via context. This is what <Provider> does.

import { shallow } from 'enzyme';
import { createStore } from 'redux';

// reducer could be a real reducer or a mock fake reducer.
const store = createStore(reducer);

it('my test', () => {
    const wrapper = shallow(
        <MyComponent>,
        { context: { store } }
    );

    // test your component here
});