react-native-testing-library
react-native-testing-library copied to clipboard
Unable to test for redux form submission
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
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
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?
@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.
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.