2016-11-11 2 views
0

Может ли кто-нибудь помочь мне с тестированием методов async/Promise в компонентах React? Например, у меня есть следующий очень простой Реагировать компонент (это только фиктивный код)Как проверить асинхронные методы в Реагировании?

import server from './server'; 

class Button extends Component { 
    async handleClick() { 
    if (await canDoSomething()) { 
     const result = await calculateIt(); 
     if (result) { 
     // will be mocked in my unit test 
     await server.sendResultToServer(result); 
     localStorage.setItem('sent', 'true'); 
     } 
     localStorage.setItem('sent', 'false'); 
    } 
    if (localStorage.getItem('sent') === 'true') { 
     // do something 
    } 
    } 

    render() { 
    return <button onClick={this.handleClick}>Click me</button>; 
    } 
} 

Теперь в моем тесте я мог издеваться большинство методов асинхронных с Синоном так:

it('should do something', async() => { 
    const promise = Promise.resolve(); 
    sinon.stub(server, 'sendResultToServer',() => promise); 
    const wrapper = shallow(<Button />); 
    wrapper.find(<button />).simulate('click'); 
    // this await will be resolved FIRST. Only then 
    // await server.sendResultToServer(result); in my code will be resolved 
    await promise; 
    expect(localStorage.getItem('sent')).to.equal('true'); 
}) 

Если вы впервые видите этот код вы должны думать, что все в порядке. Но, к сожалению, это не так. В своем тесте я ожидаю обещания await promise; и после, что я оправдываю свои ожидания. Но код реализации также ожидает обещания. Поэтому, когда обещание выполняется в , оба помещают ожидания ожидания до код в реализации выполняется. Другими словами: мой тест проходит перед тестированием кода (тестируется на моей машине с использованием Mocha/Chai/Enzyme). Мне нужен обратный порядок.

Кто-нибудь знает, как это решить?

+0

Вы никогда не вызывать обработчик щелчка в тесте –

+0

А как вы проверяете функцию handleClick()? В моем примере он находится внутри реагирующего компонента. Но я мог бы написать его над компонентом React, а не экспортировать его. Таким образом, единственный, кто может получить доступ к функции, - это обработчик кликов. – LongFlick

ответ

0

Вам нужно вызвать обработчик щелчка:

it('should do something', async() => { 
    const promise = Promise.resolve(); 
    sinon.stub(server, 'sendResultToServer',() => promise); 
    const wrapper = shallow(<Select />); 
    wrapper.simulate('click') 
    await promise; 
    expect(localStorage.getItem('sent')).to.equal('true'); 
}) 
+0

Ах, извините, мой плохой. Это происходит, когда я делаю копию и вставляю. Я уже сделал это, и это точно моя проблема: * после * события, обещание не гарантировано. Обещание в тесте разрешается раньше, чем обещание в моем коде. Я буду обновлять/исправлять свой вопрос. – LongFlick

+0

Как насчет 'canDoSomething', откуда он исходит, похоже, что это должно быть издевательствовано так же хорошо –

+0

Это хороший вопрос. В моем коде на данный момент нет «выхода». Представьте себе, что я перенаправляюсь на новый маршрут в этот момент. Или я ничего не делаю здесь. Я только показываю ошибку, если это происходит. Если ошибка не возникает (send = true), я ничего не делаю. Возможно, у меня есть какая-то архитектурная проблема, чем больше я думаю об этом. – LongFlick