2016-07-11 10 views
8

हर कोई।प्रतिक्रिया एंजाइम - टेस्ट `घटकडिडमाउंट 'Async कॉल

componentDidMount में होने वाली एसिंक कॉल के बाद मुझे राज्य अपडेट का परीक्षण करने के साथ अजीब समस्याएं आ रही हैं।

'use strict'; 


import React from 'react'; 
import UserComponent from './userComponent'; 
const request = require('request'); 


class UsersListComponent extends React.Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     usersList: [] 
    }; 
    } 

    componentDidMount() { 
    request('https://api.github.com/users', (err, res) => { 
     if (!err && res.statusCode === 200) { 
     this.setState({ 
      usersList: res.slice(0) 
     }); 
     } 
     else { 
     console.log(err); 
     } 
    }); 
    } 

    render() { 
    if (!this.state.usersList.length) { 
     return null; 
    } 

    return (
     <div className="users-list"> 
     { this._constructUsersList() } 
     </div> 
    ); 
    } 

    _constructUsersList() { 
    return this.state.usersList.map((user, index) => { 
     return (
     <UserComponent 
       key={ index } 
       name={ user.name } 
       age={ user.age } /> 
    ); 
    }); 
    } 
}; 


export default UsersListComponent; 

अब, मैं अपने परीक्षण फाइलों में क्या कर रही हूं (मैं एक सेटअप मोचा + चाय + सिनोन के शामिल है, सभी कार्य):

import React from 'react'; 
import { expect } from 'chai'; 
import { shallow, mount, render } from 'enzyme'; 
import sinon from 'sinon'; 
import UsersListComponent from '../src/usersListComponent'; 


describe('Test suite for UsersListComponent',() => { 
    it('Correctly updates the state after AJAX call in `componentDidMount` was made',() => { 
    const server = sinon.fakeServer.create(); 
    server.respondWith('GET', 'https://api.github.com/users', [ 
     200, 
     { 
     'Content-Type': 'application/json', 
     'Content-Length': 2 
     }, 
     '[{ "name": "Reign", "age": 26 }]' 
    ]); 
    let wrapper = mount(<UsersListComponent />); 
    server.respond(); 
    server.restore(); 
    expect(wrapper.update().state().usersList).to.be.instanceof(Array); 
    console.log(wrapper.update().state().usersList.length); 
    }); 
}); 

यहाँ मेरी घटक कोड है

राज्य अपडेट नहीं होता है, भले ही मैं रैपर पर update() पर कॉल करता हूं। लंबाई अभी भी है 0. क्या मुझे यहां कुछ याद आ रही है? क्या मुझे सर्वर प्रतिक्रिया को किसी अन्य तरीके से नकल करने की ज़रूरत है?

सहायता के लिए Thnx!

उत्तर

1

मैंने https://www.npmjs.com/package/request पर एक नज़र डाली और यह पता लगाया कि कॉलबैक से 'बॉडी' पैरामीटर गुम है।

ऐसा लगता है कि

... 
request('https://api.github.com/users', (err, res, body) => { 
    if (!err && res.statusCode === 200) { 
     this.setState({ 
     usersList: body.slice(0) 
     }); 
    } 
... 
+1

वास्तव में ऐसा करता है। मुझे निश्चित रूप से इसके साथ कोई समस्या थी, लेकिन इसने वास्तविक समस्या को हल नहीं किया। तो मैंने अंततः इसे बाहर काम किया। बाहर निकलता है मुझे इसकी एसिंक प्रकृति के कारण टाइमआउट में सेटस्टेट की जांच करनी पड़ती थी। अंतिम कार्यान्वयन - https://github.com/r31gN/tdd-react-enzyme/blob/master/tests/tests.full.js (मैं भी 'superagent' पर स्विच किया गया, बस व्यक्तिगत वरीयता)। –

+2

सर्वर प्रतिक्रिया को नकल करने के लिए 'nock' भी उपयोग किया जाता है। Sinon में नकली सर्वर के साथ अजीब मुद्दों था। अनुरोध पकड़ा नहीं जा रहा था। मुझे उसमें गहराई से खोदना पड़ सकता है (शायद मैं वहां कुछ मजेदार चीजें कर रहा था)। –

9

दिखना चाहिए आप कर सकते हैं सार उपयोगकर्ता सूची पुनर्प्राप्ति प्रतिक्रिया घटक से दूर एक समारोह है कि एक वादा रिटर्न गुजर के माध्यम से ऐसा करने के बजाय

componentDidMount() { 
    request('https://api.github.com/users', (err, res) => { 
     if (!err && res.statusCode === 200) { 
     this.setState({ 
      usersList: res.slice(0) 
     }); 
     } 
     else { 
     console.log(err); 
     } 
    }); 
    } 

साथ यह बदलें कि
componentDidMount() { 
    var comp = this; 
    this.props.getUsers() 
     .then(function(usersList) { 
      comp.setState({ 
      usersList: usersList 
      }); 
     }) 
     .catch(function (err) { 
      console.log(err); 
     }); 
    } 

और आपके परीक्षण मैक के अंदर फ़ंक्शन:

it('Correctly updates the state after AJAX call in `componentDidMount` was made', (done) => { 

     let resolveGetUsers; 

     let getUsers = function() { 
     return new Promise(function (resolve, reject) { 
        resolveGetUsers = resolve; 
       }); 
     } 

     let wrapper = mount(<UsersListComponent getUsers={getUsers} />); 

     resolveGetUsers([{ "name": "Reign", "age": 26 }]); 


     // promise resolve happens in a subsequent event loop turn so move assertions inside setImmediate 
     setImmediate(() => { 

     expect(wrapper.update().state().usersList).to.be.instanceof(Array); 
     ... 

     done(); 
     }); 
    } 

ध्यान दें कि मैंने यह किया है और यह मेरे लिए काम करता है (यहां तक ​​कि wrapper.update() भाग के बिना) और यहाँ मैं इसे चलाने के बिना अपने कोड उदाहरण से इसे लागू करने की कोशिश की ..

इसके अलावा ध्यान दें कि इसे अन्य मामलों में काम करना चाहिए तो घटकडिडमाउंट भी - उदाहरण के लिए बटन पर क्लिक करने के बाद एसिंक एक्शन ट्रिगर किया गया है ..

संबंधित मुद्दे