mardi 17 octobre 2017

Working with jest in react-native app with redux

based on this other question made by me and the answer given by the user @Freez, I have created a test project with a simple redux structure.

What happens is that I am trying to access the states that change within the component and it is not possible to see the changes of the reducer. But if I check the reducer inside my test file, if I can see it.

Code:

JestTestScreen file

import React, { Component } from 'react'
import { ScrollView, Text, TextInput } from 'react-native'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux';
import { text_input_typing } from '../Reducers/JestReducer'

class JestTestScreen extends Component {
  render() {
    console.log('this.props.jest.inputValue ==> ', this.props.jest.inputValue);
    return (
      <ScrollView>
        <TextInput
          style=
          value={this.props.jest.inputValue}
          placeholder={'jest test'}
          onChangeText={(text) => {
            console.log('HERE ONCHANGE!!! ==> ', text);
            this.props.text_input_typing(text)
          }} />

        <Text>{this.props.jest.inputValue}</Text>
      </ScrollView>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    jest: state.jest
  }
}

const mapDispatchToProps = (dispatch) => bindActionCreators({
  text_input_typing
}, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(JestTestScreen)

JestReducer file

const TEXT_INPUT_TYPING = 'jest/TEXT_INPUT_TYPING';

// Initial state.
const initialState = {
  inputValue: '',
};

// Reducer.
export default function reducer(state = initialState, action) {
  console.log('reducer action ==> ', action);
  switch (action.type) {
    case TEXT_INPUT_TYPING:
      return {
        ...state,
        inputValue: action.value
      }
    default:
      return state
  }
}

export const text_input_typing = (value) => {
  console.log('Here action value!!! ===> ', value);
  return { type: TEXT_INPUT_TYPING, value }
};

TEST FILE

import React from 'react'

import { createStore, combineReducers } from 'redux';
import jest from '../App/Reducers/JestReducer';

import { shallow } from 'enzyme'

import JestTestScreen from '../App/Containers/JestTestScreen'

// create a real store with the needed reducer(s)
const store = createStore(combineReducers({ jest: jest }));

const wrapper = shallow(
  <JestTestScreen />,
  { context: { store } },
);


test('>>>>> Login button Press', () => {
  let render = wrapper.dive();

  const state1 = store.getState();
  console.log('state1 ===> ', state1);

  const textInput = render.find('TextInput').first();
  console.log(`textInput2 ====>`, textInput.getNode().props);

  textInput.first().simulate('changeText', 'My new value inside!!!')

  render = wrapper.update().dive();

  const textInput2 = render.find('TextInput').first();
  console.log(`textInput2 ====>`, textInput2.getNode().props);

  const state2 = store.getState();
  console.log('state2 ===> ', state2);
});

when i call simulate i can see the logs inside JestTestScreen file->onChangeText function and i can also confirm that it is coming into action within the reducer.

But this log:

console.log('this.props.jest.inputValue ==> ', this.props.jest.inputValue);

never change, remains in its initial state as empty.

My Jest Logs.

console.log App/Containers/JestTestScreen.js:13
    this.props.jest.inputValue ==>  

  console.log __tests__/App.js:39
    state1 ===>  { jest: { inputValue: '' } } (==> Is good)

  console.log __tests__/App.js:42
    textInput2 ====> { style: 
       { marginTop: 100,
         borderWidth: 1,
         borderColor: 'black',
         borderRadius: 6,
         marginBottom: 15,
         width: 100 },
      value: '', ==> Is good
      placeholder: 'jest test',
      onChangeText: [Function: onChangeText] }

  console.log App/Containers/JestTestScreen.js:21
    HERE ONCHANGE!!! ==>  My new value inside!!!

  console.log App/Reducers/JestReducer.js:23
    Here action value!!! ===>  My new value inside!!!

  console.log App/Reducers/JestReducer.js:10
    reducer action ==>  { type: 'jest/TEXT_INPUT_TYPING',
      value: 'My new value inside!!!' }

  console.log App/Containers/JestTestScreen.js:13
    this.props.jest.inputValue ==>  ( ==> !HERE! when render is executed again, the value remains empty )

  console.log __tests__/App.js:49
    textInput2 ====> { style: 
       { marginTop: 100,
         borderWidth: 1,
         borderColor: 'black',
         borderRadius: 6,
         marginBottom: 15,
         width: 100 },
      value: '', (==> Is bad, should be 'My new value inside!!!')
      placeholder: 'jest test',
      onChangeText: [Function: onChangeText] }

  console.log __tests__/App.js:53
    state2 ===>  { jest: { inputValue: 'My new value inside!!!' } }

According to @Freez answer, the line :

// Force the component to update after changing state 
`render = wrapper.update().dive();`

but it does not work that way for me.

The strange thing is that when I print the state inside my test file, you can see that the state has changed, but the component has not updated that change even if the render was executed again

Aucun commentaire:

Enregistrer un commentaire