2016-03-10 7 views
10

Komponente:componentDidMount setState nicht in Enzymtest reflektierenden

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) 
    }) 
}) 

Die ersten zwei Prüfungen bestehen, aber der letzte nicht der Fall, dh wrapper.state ('Katzen') .length == 0

Ich verstehe, dass setState nicht garantiert, Status sofort zu aktualisieren, aber wenn ich 'Katzen' in der Komponente protokolliere, kann ich es aktualisieren sehen.

Antwort

7

Wenn Sie den Status in Ihrer Komponente in einem Kontext festlegen, den das Enzym nicht kennt, müssen Sie manuell .update() auf dem Wrapper aufrufen, damit er die aktualisierte Version der Rendering-Struktur erhält.

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

versucht, aber es hat nicht funktioniert. –

+0

Das funktionierte für mich, ich aber gefragt, warum es als Folge der setState nicht aktualisiert, wird die Hülle eine Kopie des Baumes oder etwas machen durchqueren? – riscarrott

+0

Leland, brauchen Sie nicht zuerst, um sicherzustellen, dass staatliche Update passiert vor wrapper.update tun()? – bodrin

1

Ich hatte ein ähnliches Problem und es war notwendig, ein Versprechen von dem it Rückruf und überprüfen Sie die Erwartung in der then Methode der Versprechen zurückzukehren.

In Ihrem Fall (unter der Annahme ajaxFn ein Versprechen war, oder man könnte es in eine Umdrehung) Ich denke, das etwa sein würde:

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