当模拟点击调用一个调用

当模拟点击调用一个调用

本文介绍了当模拟点击调用一个调用 promise 的函数时,使用 React 的 Jest 和 Enzyme 进行测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • React v15.1.0
  • Jest v12.1.1
  • 酶 v2.3.0

我想弄清楚如何测试在单击调用的函数中调用 promise 的组件.我期待 Jest 的 runAllTicks() 函数在这里帮助我,但它似乎没有执行承诺.

组件:

从'react'导入React;从蓝鸟"导入承诺;函数 doSomethingWithAPromise() {返回新的承诺((解决)=> {setTimeout(() => {解决();}, 50);});}导出默认类 AsyncTest 扩展 React.Component {构造函数(道具){超级(道具);this.state = {承诺文本:'',超时文本:''};this.setTextWithPromise = this.setTextWithPromise.bind(this);this.setTextWithTimeout = this.setTextWithTimeout.bind(this);}setTextWithPromise() {返回 doSomethingWithAPromise().then(() => {this.setState({ promiseText: '有文字!' });});}setTextWithTimeout() {setTimeout(() => {this.setState({ timeoutText: '有文字!' });}, 50);}使成为() {返回 (<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}>超时</button>

);}}

还有测试:

从'../async'导入AsyncTest;从酶"导入{浅};从反应"导入反应;jest.unmock('../async');描述('async-test.js', () => {让包装;beforeEach(() => {包装器 = 浅(<AsyncTest/>);});//失败it('点击按钮后显示承诺文本', () => {wrapper.find('#promiseBtn').simulate('click');jest.runAllTicks();jest.runAllTimers();包装器更新();expect(wrapper.find('#promiseText').text()).toEqual('有文字!');});//经过it('点击按钮后显示超时文本', () => {wrapper.find('#timeoutBtn').simulate('click');jest.runAllTimers();包装器更新();expect(wrapper.find('#timeoutText').text()).toEqual('有文字!');});});
解决方案

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

  1. 独立测试 onClick 和您的承诺方法.因此,检查 onClick 是否调用了正确的函数,但监视 setTextWithPromise,触发点击并断言 setTextWithPromise 被调用.然后,您还可以获取组件实例并调用返回承诺的方法,您可以附加处理程序并断言它做了正确的事情.

  2. 公开一个你可以传入的回调道具,当承诺解析时调用.

  • React v15.1.0
  • Jest v12.1.1
  • Enzyme v2.3.0

I'm trying to figure out how to test a component that calls a promise in a function invoked by a click. I was expecting Jest's runAllTicks() function to help me out here, but it doesn't seem to be executing the promise.

Component:

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

And the tests:

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!');
  });
});
解决方案

There isn't much around needing to somehow wait for the promise to fulfill before ending the test. There are two main ways of doing it from your code that I can see.

  1. independently test that onClick and your promise methods. So check that onClick calls the correct function, but spying on setTextWithPromise, triggering a click and asserting that setTextWithPromise was called. Then you can also get the component instance and call that method which returns the promise you can attach a handler and assert it did the right thing.

  2. expose a callback prop that you can pass in that is called when the promise resolves.

这篇关于当模拟点击调用一个调用 promise 的函数时,使用 React 的 Jest 和 Enzyme 进行测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 12:01