2016-03-10 19 views
10

Component:componentDidMount setstate không phản ánh trong thử nghiệm Enzyme

import React from 'react' 
import request from 'superagent' 

export default React.createClass({ 
    getInitialState() { 
     return {cats: []} 
    }, 

    componentDidMount() { 
     request('/api', (err, res) => { 
      if (err) return; 
      this.setState({ 
       cats: res.body.results 
      }) 
     }) 
    }, 

    render() { 
     let cats = this.state.cats 
     let catsList = (
      <ul> 
       {cats.map((c) => <li key={c.id}>cat</li>)} 
      </ul> 
     ) 
     return (
      <div> 
       hello world 
       {cats.length ? catsList : null} 
      </div> 
     ) 
    } 
}) 

Test:

jest.unmock('../app.js') 
jest.unmock('superagent') 

import React from 'react' 
import {mount} from 'enzyme' 
import nock from 'nock' 
import App from '../app.js' 

describe('App',() => { 
    let ajaxFn 
    beforeEach(() => { 
     ajaxFn = nock('http://localhost') 
      .get('/api') 
      .reply(200, { 
       results: [{id: 1}, {id: 2}, {id: 3}] 
      }) 
    }) 

    it('says hello world',() => { 
     let wrapper = mount(<App/>) 
     expect(wrapper.text()).toContain('hello worl') 
    }) 

    it('makes ajax request',() => { 
     let wrapper = mount(<App/>) 
     expect(ajaxFn.isDone()).toBe(true) 
    }) 

    it('renders correct number of cats',() => { 
     let wrapper = mount(<App />) 
     expect(wrapper.state('cats').length).toBe(3) 
    }) 
}) 

2 bài kiểm tra đầu tiên vượt qua nhưng một trong những thức không, tức là wrapper.state ('mèo') .length == 0

Tôi hiểu rằng setState không đảm bảo cập nhật trạng thái ngay lập tức, tuy nhiên nếu tôi đăng nhập 'mèo' trong thành phần, tôi có thể thấy cập nhật.

Trả lời

7

Nếu bạn kết thúc thiết lập trạng thái trong thành phần của bạn trong một số ngữ cảnh mà enzyme không biết, bạn sẽ phải tự gọi .update() trên trình bao bọc để nó có được phiên bản cập nhật của cây hiển thị.

it('renders correct number of cats',() => { 
    let wrapper = mount(<App />) 
    expect(wrapper.update().state('cats').length).toBe(3) 
}) 
+6

Cố gắng đó, nhưng nó đã không làm việc. –

+0

Điều này làm việc cho tôi, tôi tự hỏi tại sao nó không cập nhật như là kết quả của setState, hiện các wrapper đi qua một bản sao của cây render hoặc một cái gì đó? – riscarrott

+0

Leland, bạn không cần phải đảm bảo đầu tiên cập nhật trạng thái đó đã xảy ra trước khi thực hiện wrapper.update()? – bodrin

1

Tôi đã có một vấn đề tương tự và nó là cần thiết để trả lại một lời hứa từ it gọi lại và kiểm tra các kỳ vọng trong phương pháp then của lời hứa.

Trong trường hợp của bạn (giả sử ajaxFn là một lời hứa, hoặc bạn có thể biến nó thành một) Tôi nghĩ rằng đây sẽ là khoảng:

it('renders correct number of cats',() => { 
    let wrapper = mount(<App />) 
    return ajaxFn.then(() => { 
     expect(wrapper.state('cats').length).toBe(3); 
    } 
}) 
Các vấn đề liên quan