2017-10-05 12 views
0

Ich versuche, eine Texteingabe zu füllen und zu überprüfen, dass der Text korrekt ausgefüllt ist, auf die Komponente zugreifen und seinen Wert erhalten.Verwendung von Test für Test reactive-native - Redox-App

Ich habe es geschafft, aber ohne redux, dh mit den nativen Zuständen von react-native. this.state.

Component Code:

//inside constructor 
this.state = { 
    email: '' 
} 

<TextInput value={this.state.email} onChangeText={(text) => { 
    console.log('Here change email text!!! ==> ', text); 
    this.setState({ 
    email: text 
    }) 
}} /> 

Testdatei Code:

import LoginScreen from '../../App/Containers/LoginScreen' // => connected component.. exported with `export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)` 
import configureStore from 'redux-mock-store' 
import { shallow } from 'enzyme' 

import Actions, { reducer, INITIAL_STATE } from '../../App/Redux/Reducers/UserReducer' 


const initialState = { 
    user: { 
    email: 'mockState email', 
    password: '', 
    requesting: 0, 
    userData: null, 
    loginFinish: false, 
    errorMessage: null 
    } 
} 

const mockStore = configureStore([]); 
let store = mockStore(initialState); 

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

test('>>>>> LoginScreen component renders correctly',() => { 
    expect(wrapper.dive()).toMatchSnapshot(); 
}); 


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

    const textInputProps = render.find('TextInput'); //getting text input from render 
    console.log(`textInputProps.getNode(1).props.value BEFORE ====>`, textInputProps.getNodes()[0].props.value); 

    textInputProps.first().simulate('changeText', 'My new value'); // executing onChangeText inside render of component 

    const textInputProps2 = render.find('TextInput'); //getting text input again for check changes 
    console.log(`textInputProps2.getNode(1).props.value====>`, textInputProps2.getNodes()[0].props.value); 

    const state = store.getState(); //verifying internal `initialState`.. NOT CHANGES 
    console.log('state ===> ', state); 

}); 

Ich habe auf this link

Lauf Prüfprotokolle verlassen

yarn test v0.24.6 
$ jest 
PASS Tests/Containers/loginScreenTest.js 
    ✓ >>>>> LoginScreen component renders correctly (282ms) 
    ✓ >>>>> Login button Press (33ms) 

    console.log Tests/Containers/loginScreenTest.js:60 
    textInputProps.getNode(1).props.value BEFORE ====> 

    console.log App/Containers/LoginScreen.js:124 
    Here change email text!!! ==> My new value 

    console.log Tests/Containers/loginScreenTest.js:67 
    textInputProps2.getNode(1).props.value====> My new value => (!!!WORKS!!!) 

    console.log Tests/Containers/loginScreenTest.js:86 
    state ===> { user: 
     { email: 'mockState email', 
     password: '', 
     requesting: 0, 
     userData: null, 
     loginFinish: false, 
     errorMessage: null } } 

Test Suites: 1 passed, 1 total 
Tests:  2 passed, 2 total 
Snapshots: 1 passed, 1 total 
Time:  2.337s, estimated 3s 
Ran all test suites. 
✨ Done in 3.10s. 

wie Sie in den Protokollen sehen textInputProps2.getNode(1).props.value ====> zeigen Sie mir den Wert wie erwartet.

So far so good

Jetzt ist alles zu einem Druckminderer, mit der redux Struktur vorbei, werden wir die Texteingabe sehen, wie

<TextInput value={this.props.user.email} style={styles.textInputs} placeholder={'Email'} autoCapitalize={'none'} onChangeText={(text) => { 
    console.log('Here change email text!!! ==> ', text); 
    this.props.email_typing(text); 
}} /> 

Connected Logik

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

const mapDispatchToProps = (dispatch) => { 
    return { 
    email_typing: (text) => dispatch(UserReducer.email_typing(text)), 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen) 

Meine UserReducer Datei folgt

import { createReducer, createActions } from 'reduxsauce' 
import Immutable from 'seamless-immutable' 

/* ------------- Types and Action Creators ------------- */ 

const { Types, Creators } = createActions({ 
    email_typing: ['email'], 
}) 

export const LoginTypes = Types 
export default Creators 

/* ------------- Initial State ------------- */ 

export const INITIAL_STATE = Immutable({ 
    email: '' 
}) 

/* ------------- Reducers ------------- */ 


// state.merge undefined error: https://github.com/infinitered/ignite/pull/20#issuecomment-202550408. Fixed including in Inmutable 
export const emailTyping = (state, { email }) => { 
    console.log('Email Typing changes !!! in original reducer') 
    return Immutable(state).merge({ email }) 
} 


/* ------------- Hookup Reducers To Types ------------- */ 

export const reducer = createReducer(INITIAL_STATE, { 
    [Types.EMAIL_TYPING]: emailTyping, 
}) 

diese Änderung gegeben, ist die Idee, dass die initialState innerhalb der Testdatei Änderungen INITIAL_STATE importiert Wert.

Etwas wie:

const mockStore = configureStore([]); 
let store = mockStore(INITIAL_STATE); 

aber, wenn ich den Test erneut aus. Zeigen Sie mir den nächsten Fehler:

● >>>>> LoginScreen component renders correctly 

    TypeError: Cannot read property 'email' of undefined 

auch wenn ich die initial anstatt die initial_state halten, ich habe nicht den obigen Fehler, aber ich kann nicht die Texteingabe erhalten Sie die Änderung zu übernehmen.

Lauf Prüfprotokolle

yarn test v0.24.6 
$ jest 
PASS Tests/Containers/loginScreenTest.js 
    ✓ >>>>> LoginScreen component renders correctly (345ms) 
    ✓ >>>>> Login button Press (24ms) 

    console.log Tests/Containers/loginScreenTest.js:58 
    textInputProps.getNode(1).props.value BEFORE ====> mockState email 

    console.log App/Containers/LoginScreen.js:120 
    Here change email text!!! ==> My new value 

    console.log Tests/Containers/loginScreenTest.js:61 
    textInputProps2.getNode(1).props.value====> mockState email => **(!! HERE !!!, THE VALUE IS BEING THE PREVIOUS ONE AND IGNOR THE CHANGE)** 

    console.log Tests/Containers/loginScreenTest.js:79 
    state ===> { user: 
     { email: 'mockState email', 
     password: '', 
     requesting: 0, 
     userData: null, 
     loginFinish: false, 
     errorMessage: null } } 

Test Suites: 1 passed, 1 total 
Tests:  2 passed, 2 total 
Snapshots: 1 passed, 1 total 
Time:  2.904s 
Ran all test suites. 
✨ Done in 3.68s. 

prüfen textInputProps2.getNode(1).props.value====> Protokoll zu überprüfen, dass dies nicht sinnvoll ist.

I think that the const initialState declared inside test file It is not being affected by the changes made in the actual reducer when this.props.email_typing(text) action is called;

Ich habe nicht die Art und Weise zu verbinden, die Aktionen mit den Zuständen in den Minderer und in der Lage sein laden sie innerhalb JEST gefunden.

Ich weiß, es ist ein bisschen lang und ich schätze Ihre Zeit beim Lesen. Ich habe versucht, es so gut wie möglich zu erklären. Vielen Dank und ich freue mich auf jede Antwort.

+0

Import von Login‘../../App/ Containers/LoginScreen '// => verbundene Komponente .. exportiert mit 'export default connect (mapStateToProps, mapDispatchToProps) (LoginScreen) Das klingt nach einem Importproblem, haben Sie auch die Komponente exportiert (Sie sollten 2 Exporte in Ihrer getesteten Datei haben) , eine für die Verbindung und eine für die tatsächliche Komponente) – Eran

Antwort

1

Ich denke, Sie möchten hier einen Integrationstest durchführen. Es ist möglich, zu erreichen, was du so versuchen:

import { createStore, combineReducers } from 'redux'; 
import { reducer } from '.../UserReducer'; 

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

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

// ... 

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

    const textInputProps = render.find('TextInput'); 
    console.log(`value BEFORE ====>`, textInputProps.getNodes()[0].props.value); 

    textInputProps.first().simulate('changeText', 'My new value'); 

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

    const textInputProps2 = render.find('TextInput'); 
    console.log(`value AFTER ====>`, textInputProps2.getNodes()[0].props.value); 

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

Ich habe versucht, mit einer minimalen Implementierung, hier ist die Konsole Ergebnis:

console.log src/Test.test.js:27 
value BEFORE ====> 

console.log src/Test.test.js:35 
value AFTER ====> My new value 

console.log src/Test.test.js:38 
state ===> { user: { email: 'My new value' } } 
+0

Die Änderung im Zustand funktioniert gut, aber "Wert nachher" Protokoll noch leer. Ich drucke 'this.props.user.email' innerhalb des Renderings von' LoginScreen' und immer noch leer. Aber wenn ich 'store.getState()' drucke, kann ich die Änderung sehen – jose920405

+0

Funktioniert für mich, wenn ich 'shallow' noch einmal vor' wrapper.update(). Dive(); 'Es scheint, als ob etwas nicht benötigt wird, Hast du eine Idee warum? – jose920405