Компонент, создающий аксиальный запрос, монтируется дважды, чтобы пройти асинхронный тест, если он монтируется после неудачного теста.ЗАЧЕМ - PullRequest
0 голосов
/ 01 февраля 2019

Я звоню на внутренний сервер, чтобы вернуть мне любые данные, и для этого я использую axios-mock-adapter и отправляю обратно массив из 5 вещей.Мне нужно смонтировать компонент дважды, чтобы пройти этот тест.вот мой компонент:

   import React, { Component, Fragment } from 'react'
   import axios from 'axios'

  export default class HelloWorld extends Component {
     constructor(props) {
       super(props)
       this.state = {
        goodbye: false,
        data: []
    }
}

async componentDidMount() {
    await this.func()
    console.log("RUNNING");
}

func = async () => {
    let data;
    try {
        data = await axios.get('http://localhost:8080');
    }
    catch(e) {
        console.log("ERROR");
        throw(e)
    }

    this.setState({data: data.data})

}

goodbye = () => {
    this.setState((state, currentProps) => ({...state, goodbye: !state.goodbye}))
}

render() {
    return (
        <Fragment>
            <h1>
                Hello World
            </h1>
            <button id="test-button" onClick={this.goodbye}>Say Goodbye</button>
            {
                !this.state.goodbye ? null :
                <h1 className="goodbye">GOODBYE WORLD</h1>
            }
        </Fragment>
    )
}

}

и вот тест:

it('there is data being returned', async () => { 

    let mock = new MockAdapter(axios)
    const data = new Array(5).fill('Hello World')

    mock.onGet('http://localhost:8080').reply(200, data)

    const component =  await mount(<HelloWorld />) 


    //if this line below is commented out the test fails
    await component.instance().componentDidMount();

    expect(component.state('data')).toHaveLength(5)

})

не уверен, почему я должен смонтировать компонент, а затем смонтировать его снова,У кого-нибудь есть идеи?

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Реакция ложных осей происходит асинхронно, поэтому вы не получите ответ до следующего тика цикла событий.Эта строка:

await component.instance().componentDidMount();

ожидает ответа перед продолжением синхронной операции, поэтому она работает, когда она есть, и не работает, когда вы удаляете эту строку.Есть несколько других решений, которые будут работать - Вы можете заменить эту строку на:

await Promise.resolve();

или использовать вспомогательную функцию, например, такую:

const wait = () => new Promise(resolve => setTimeout(resolve, 0));

и заменить await component.instance().componentDidMount();с этим:

await wait();

Любой из них будет ожидать один тик цикла событий, что позволит возвращаемому ответу вернуться.Вам также может понадобиться позвонить component.update() после того, как вы получите ложные данные.Еще одна вещь: mount(<HelloWorld />) является синхронной и не возвращает обещание, поэтому нет необходимости await его.

0 голосов
/ 01 февраля 2019

Решил это, поставив beforeEach и передав ему () следующим образом:

 beforeEach( async (done) => {

    let mock = new MockAdapter(axios)
    const data = new Array(5).fill('Hello World')

    mock.onGet('http://localhost:8080'). reply(200, data)

    component =  await mount(<HelloWorld />)  

    done()
 })
...