react-native-testing-library icon indicating copy to clipboard operation
react-native-testing-library copied to clipboard

Unable to test for redux form submission

Open Brad19 opened this issue 4 years ago • 2 comments

Ask your Question

Can someone pls help to test the redux form submission using react native testing (version 7.1.0). I'm using redux-mock-store to mock the store and i'm able to fire the change event. But i need is to test the form submission. I was trying different ways, but not sure how to test the form submit with the values that are getting passed and the subsequent dispatch action calls. Please advise as i'm relatively new to this echo system.

Could anyone kindly help me as i've been struck on this.

Here is the Component

class Register extends React.Component {
...
submit = (values: RegisterFormProps) => {

    const { register } = this.props;
    console.log('values :', values);
    Keyboard.dismiss();
    const sleep = (ms = 100) => new Promise(resolve => setTimeout(resolve, ms))
    return sleep().then(() => register(values));

  }

render() {
return(<>
...
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
                <View style={styles.box}>
                  <Field
                    name="firstName"
                    component={UITextInput}
                    ...
                    accessibilityLabel='firstName'
                  />
                  <Field
                    name="lastName"
                    component={UITextInput}
                    ...
                    accessibilityLabel='lastName'
                  />
                  <Field
                    name="email"
                    component={UITextInput}
                    ...
                    accessibilityLabel='email'
                  />
                  <Field
                    name="password"
                    component={UITextInput}
                    secureTextEntry={true}
                    ...
                    accessibilityLabel='password'
                  />
                  <Field
                    name="mobileNumber"
                    component={UITextInput}
                    ...
                    accessibilityLabel='mobileNumber'
                  />
                  <View style={styles.buttonContainer}>
                    <Field
                      name="Register"
                      component={UIButton}
                      onPress={
                        handleSubmit(this.submit)
                      }
                      accessibilityLabel={'registerButton'}
                    />
                  </View>
                </View>
              </TouchableWithoutFeedback>
</>)
}

}

Container for the component

const mapStateToProps = (state: StateProps) => {
  return ({
    isloading: state.user.isLoading,
    token: state.user?.token,
  })
};

const mapDispatchToProps = (dispatch: any) => ({
  register: (user: RegisterFormProps) => dispatch(userRegistration(user))
});



const ReduxComponent = reduxForm<RegisterFormProps>({ form: 'register' })(Component as React.ComponentType<any>);
React.ComponentType<InjectedFormProps<FormProps>>)

const splashContainer = connect(
  mapStateToProps,
  mapDispatchToProps,
)(ReduxComponent);

ContainerTest

import { renderWithRedux } from './test-utils/render';

const initialState = {
    user: {
        isLoading: false,
        token: '',
    }
};

function renderRegistrationScreen(props: IProps) {
    return renderWithRedux(<Container {...props} />, { initialState });
};

describe('Register', () => {

    const mockSubmit = jest.fn();
    const mockHandleSubmit = jest.fn(); // I tried mock implementation, but the values are not coming thru.

    const props: IProps = {
        componentId: '1',
        isloading: false,
        submit: mockSubmit,
        token: '',
        handleSubmit: mockHandleSubmit,
        register: jest.fn()
    }

    it('register the user', async () => {
        const wrapper = renderRegistrationScreen(props);
        const { getByTestId, getByText, store } = wrapper;
        expect(fireEvent.changeText(getByTestId('firstName'), 'Harry'));
        expect(fireEvent.changeText(getByTestId('lastName'), 'Potter'));
        expect(fireEvent.changeText(getByTestId('email'), '[email protected]'));
        expect(fireEvent.changeText(getByTestId('password'), 'ABCD123'));
        expect(fireEvent.changeText(getByTestId('mobileNumber'), '0111112222'));
        expect(fireEvent.press(getByText('Register'))); //I've verified that this Register button is pressed
        expect(mockHandleSubmit).toHaveBeenCalledTimes(1);
        // intentionally to check what it returns and it returns [Function bound] and i could not test the values for the form submission
        expect(mockHandleSubmit).toBeCalledWith('something')
        expect(mockSubmit).toBeCalledWith('...');
        **// Here is what i get struck I want to verify the values that i'm passing in handleSubmit
        // Want to check if the submit function is called if possible
        // Want to check if the dispatch register function is called with right values
        // Is that possible to get the mock payload of the dispatch userRegistration which is called in mapDispatchToProps
        **
        
    });

testUtils/render

import { Provider } from 'react-redux';
import { render } from '@testing-library/react-native';
import configureStore from 'redux-mock-store';
import * as thunkMiddleware from 'redux-thunk';

let middlewares = [thunkMiddleware.default];

const logger = require('redux-logger');
// The following logger is added just to confirm the change event - will be removed once tests are working as expected
const loggerMiddleware = logger.createLogger({
  duration: true,
});
middlewares = [...middlewares, loggerMiddleware];

const mockStore = configureStore(middlewares)

export function renderWithRedux(component: any, { initialState }: any = {}) {

  const store = mockStore(initialState);

  const queries = render(<Provider store={store}>{component}</Provider>);

  return {
    ...queries,
    store,
  };
};

Brad

Brad19 avatar Mar 27 '21 19:03 Brad19

Are you sure the sleep().then(() => register(values)); is getting executed due to the way timers are handled in Jest?

https://jestjs.io/docs/timer-mocks

janithl avatar Apr 12 '21 05:04 janithl

Hello @Brad19, Is it possible for you to make a reproduction case it is really hard to read and understand the code in plain text?

guvenkaranfil avatar Oct 15 '21 15:10 guvenkaranfil

@Brad19 could you verify that the issue you reported does still occur on the latest version of RNTL (& React Native, React, React Test Renderer). If so, could you please provide repro repository hopefully based on ours examples/basic app in our repo.

mdjastrzebski avatar Sep 26 '22 12:09 mdjastrzebski

Closing as stale.

@Brad19 If the issue still occurs on the latest version of RNTL, please provide a minimal repro repository, hopefully based on examples/basic folder from our repo, so that we can better understand the issue.

mdjastrzebski avatar Oct 16 '22 08:10 mdjastrzebski