用React的笑话和酶进行测试时,当单击点击调用一个呼叫promise的函数

问题描述 投票:0回答:2
jestv12.1.1
    e酶v2.3.0
  • 我正在尝试弄清楚如何在单击中调用的函数中调用承诺的组件。我期望开玩笑的功能能帮助我在这里,但这似乎并没有执行承诺。
  • 组件:
  • runAllTicks()
和测试:

import React from 'react';
import Promise from 'bluebird';

function doSomethingWithAPromise() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, 50);
  });
}

export default class AsyncTest extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      promiseText: '',
      timeoutText: ''
    };

    this.setTextWithPromise = this.setTextWithPromise.bind(this);
    this.setTextWithTimeout = this.setTextWithTimeout.bind(this);
  }

  setTextWithPromise() {
    return doSomethingWithAPromise()
      .then(() => {
        this.setState({ promiseText: 'there is text!' });
      });
  }

  setTextWithTimeout() {
    setTimeout(() => {
      this.setState({ timeoutText: 'there is text!' });
    }, 50);
  }

  render() {
    return (
      <div>
        <div id="promiseText">{this.state.promiseText}</div>
        <button id="promiseBtn" onClick={this.setTextWithPromise}>Promise</button>
        <div id="timeoutText">{this.state.timeoutText}</div>
        <button id="timeoutBtn" onClick={this.setTextWithTimeout}>Timeout</button>
      </div>
    );
  }
}

任意答案:
使用

import AsyncTest from '../async'; import { shallow } from 'enzyme'; import React from 'react'; jest.unmock('../async'); describe('async-test.js', () => { let wrapper; beforeEach(() => { wrapper = shallow(<AsyncTest />); }); // FAIL it('displays the promise text after click of the button', () => { wrapper.find('#promiseBtn').simulate('click'); jest.runAllTicks(); jest.runAllTimers(); wrapper.update(); expect(wrapper.find('#promiseText').text()).toEqual('there is text!'); }); // PASS it('displays the timeout text after click of the button', () => { wrapper.find('#timeoutBtn').simulate('click'); jest.runAllTimers(); wrapper.update(); expect(wrapper.find('#timeoutText').text()).toEqual('there is text!'); }); });

/
async
导致更清洁的代码。下面的旧代码 我通过组合以下元素成功解决了这个问题:
asynchronous reactjs promise jestjs enzyme
2个回答
66
投票

毫无根据并立即解决诺言 通过标记测试函数来制定测试异步

在模拟点击之后,请等到下一个
macrotask
给出了承诺的时间解决

在您的例子中,可能看起来像这样:

await
    使用此方法时,eenzyme's n n n n n dome Ampotige也不需要,因为承诺永远不会通过设计来创建的相同刻度。有关此处发生的事情的非常详细的解释,请参阅this thisQuestion
  • 原始答案:
    相同的逻辑,但略微漂亮。使用Node的
  • async
  • 将测试推迟到下一个tick,这是承诺将解决的时间。然后致电Jest的
  • // Mock the promise we're testing global.doSomethingWithAPromise = () => Promise.resolve(); // Note that our test is an async function it('displays the promise text after click of the button', async () => { wrapper.find('#promiseBtn').simulate('click'); await tick(); expect(wrapper.find('#promiseText').text()).toEqual('there is text!'); }); // Helper function returns a promise that resolves after all other promise mocks, // even if they are chained like Promise.resolve().then(...) // Technically: this is designed to resolve on the next macrotask function tick() { return new Promise(resolve => { setTimeout(resolve, 0); }) }

以异步完成测试。

update()

这不太好,因为如果您必须等待多个诺言,您会得到大嵌套回调。


在结束测试之前,并不需要以某种方式等待承诺实现的承诺。从您的代码中,我可以看到两种主要方法。


独立于测试setImmediate和您的承诺方法。因此,请检查是否调用正确的功能,但请在done

上间谍,触发单击并断言
global.doSomethingWithAPromise = () => Promise.resolve({}); it('displays the promise text after click of the button', (done) => { wrapper.find('#promiseBtn').simulate('click'); setImmediate( () => { expect(wrapper.find('#promiseText').text()).toEqual('there is text!'); done(); }) }); 被调用。然后,您还可以获取组件实例并调用该方法,该方法返回承诺您可以附加处理程序并断言它做对的事情。
在承诺解决时,可以曝光一个可以通过的回调道具。

如果您使用开玩笑,也可以使用
onClick

onClick

1
投票

setTextWithPromise
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.