1
votes

I have an issue using jest and enzymes for my unit testing on react. I have a component connected to redux and i want to test a method in my component that update the state. heres's my component :

import React, {Component} from 'react';
import Form from 'react-jsonschema-form';
import pick from 'lodash/pick';
import {bindActionCreators} from 'redux';
import fields from './fields';
import widgets from './widgets';

import {initContainerActions} from '../../utils/actionHelper';
import {actions as modelActions} from './actions';
import {connect} from '../../utils/connect';
import reducerRegistry from '../ReducerRegistry';
import reducer from './reducer';

type StateProperties = {
  roleModelSchema: Object,
  roleUiSchema: Object
};

export type FormContainerProps = {
  model: Object,
  uiSchema: Object,
  userModelLoad: Function,
  isLoading: boolean,
  idContainer: string
};

export class FormContainer extends Component<FormContainerProps, StateProperties> {
  fields = {...fields};

  widgets = {...widgets};

  constructor(props) {
    super(props);
    const {idContainer} = props;
    reducerRegistry.register(idContainer, reducer(idContainer));

    this.state = {
      roleModelSchema: {},
      roleUiSchema: {}
    };
  }

  componentDidMount = async () => {
    const {userModelLoad} = this.props;
    await userModelLoad();
    this.renderRoleForm();
  };

  renderRoleForm = () => {
    const {model, uiSchema} = this.props;
    const modelProperties = Object.keys(model.properties);
    const roleUiSchema = pick(uiSchema, modelProperties);

    this.setState({
      roleUiSchema,
      roleModelSchema: model
    });
  };

  render = () => {
    const {roleModelSchema, roleUiSchema} = this.state;
    const {isLoading} = this.props;

    if (isLoading) {
      return <div>...Loading</div>;
    }
    return (
      <div className="container">
        <div className="columns">
          <div className="column col-12">
            <Form schema={roleModelSchema} uiSchema={roleUiSchema} liveValidate fields={this.fields} widgets={this.widgets}>
              <div>
                <button type="submit" className="btn btn-primary">
                  Submit
                </button>
                <button type="button">Cancel</button>
              </div>
            </Form>
          </div>
        </div>
      </div>
    );
  };
}

const mapDispatchToProps = (dispatch, props) => {
  const initializedActions = initContainerActions(modelActions, props.idContainer);
  return bindActionCreators(initializedActions, dispatch);
};

export default connect(
  (state, props) => state[props.idContainer] || {},
  mapDispatchToProps
)(FormContainer);

And the test :

const mockStore = configureMockStore([]);
const context = React.createContext();

describe('Check if renderRoleForm update state', () => {
it('renders without crashing', () => {
// Initialize mockstore with empty state
const initialState = {roleUiSchema: {}};
const store = mockStore(initialState);
const wrapper = shallow(
  <Provider store={store} context={context}>
    <FormContainer model={model} uiSchema={uiSchema} context={context}
/>
  </Provider>
);

const instance = wrapper.instance();
instance.renderRoleForm();

expect(wrapper.state().roleUiSchema).not.toBeEmpty();
});
});

The error i have : TypeError: instance.renderRoleForm is not a function

I tried with mount, dive with shallow and same problem. If you have any idea :) Thanks

1
can you share the entire FormContainer code please?Chris Hawkes
try wrapper.dive().instance()skyboyer
I decided to not use the provider and test only the component because when you try to test a connected component you need ton import all the things related to redux !! So instead of testing only the component i tested all the redux flow..user1310969

1 Answers

1
votes
const wrapper = mount(
<Provider store={store} context={context}>
<FormContainer model={model} uiSchema={uiSchema} context={context} />
</Provider> );
//
wrapper.instance().renderRoleForm();