Search code examples
reactjsunit-testingaxiosjestjsenzyme

How to assert state in unit test (React JS) while state is updating in axios call?


hi i am having problem in asserting state in unit test case while it is updating in axios call. This is my axios call

import axios from 'axios'
getData = () => {
    axios.get('/events/sept/week2/1097338')
        .then(res =>{
            if(res.status == 200){
                let resposne = res.data.resposne
                this.setState({weekData:response})
            }
        })
        .catch(error => {console.log(error)})
}

this is my test case

test("test axios for week data",() => {
    const mock = new MockAdapter (axios)
    mock.onGet('/events/sept/week2/1097338').reply(200,{response:['raspberry']})
    const wrapper = shallow(<Component/>)
    wrapper.instance().getData()
    expect(wrapper.state('weekData')).toBe(['raspberry'])
})

the state weekData is updating in Component when i call wrapper.instance().getData(), i have checked this. Its not updating in wrapper and my assertion is failing like : expected : ['raspberry'] , received : [ ]. How to update state in wrapper i have tried setTimeout but no use


Solution

  • When a function that calls Axios is unreachable, a promise that it returns should be chained to avoid race conditions. Since MockAdapter doesn't specifically provide it, this should be done additionally:

    const wrapper = shallow(<Component/>)
    jest.spyOn(axios, 'get');
    wrapper.instance().getData()
    expect(axios.get).toBeCalledTimes(1);
    await axios.get.mock.results[0].value;
    expect(wrapper.state('weekData')).toBe(['raspberry'])
    

    For a function that is directly accessible, a promise that it returns can be chained. getData is an antipattern because it contains loose promise that cannot be chained. It should be:

    getData = () => {
        return axios.get('/events/sept/week2/1097338')
        ...
    

    Then it could be tested as:

    const wrapper = shallow(<Component/>)
    await wrapper.instance().getData()
    expect(wrapper.state('weekData')).toBe(['raspberry'])