H5W3
当前位置:H5W3 > 问答 > 正文

Testing with React’s Jest and Enzyme when simulated clicks call a function that calls a promise

  • 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!');
});
});

Answer

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.

本文地址:H5W3 » Testing with React’s Jest and Enzyme when simulated clicks call a function that calls a promise

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址