亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Axios 和 Jest 在 React 中測試異步行為

使用 Axios 和 Jest 在 React 中測試異步行為

手掌心 2022-07-08 17:39:39
考慮以下過度簡化的 React 組件。當您單擊該按鈕時,它會對外部 URL 進行 API 調用。如果成功,則遞增計數器如果不成功,則遞減計數器import axios from 'axios';import PropTypes from 'prop-types';import React from 'react';class MyCoolButton extends React.Component {  static propTypes = {    initialCounter: PropTypes.number.isRequired  };  constructor(props) {     super(props);    this.onClick = this.onClick.bind(this);    this.state = {      counter: props.initialCounter    }  }  onClick() {    const url = `/some/url/here`;    const data = { foo: 'bar' };    const config = { headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } };    const { counter } = this.state;    return axios.patch(url, data, config)      .then((response) => { /* Success! */ this.setState({ counter: counter + 1 }); })      .catch((error) => { /* Failure :( */ this.setState({ counter: counter - 1 }); });  }  render() {    return (      <div className="container">        <span>Counter value is: {this.state.counter}</span>        <input className="cool-button" type="button" onClick={this.onClick} />      </div>            );  }}export default MyCoolButton;我想使用 Jest 編寫一個測試用例,以確保在出現故障時,我們正確地減少按鈕。我嘗試了以下方法:describe('an error occurred while updating', () => {  beforeEach(() => {    axios.patch.mockImplementationOnce(() => Promise.reject('boo'));  });  it('decrements the counter', async() => {    // NOTE: The below uses Enzyme and Chai expectation helpers    wrapper = mount(<MyCoolButton initialCounter={99} />);    // Click the button    wrapper.find(`.cool-button`).first().simulate('click');    // Check for decrmented value    const body = wrapper.find('.container span');    expect(body).to.have.text('Counter value is: 98');  });});問題是點擊和后續state更新是異步執行的,所以我們在它有機會更新失敗的組件之前檢查失敗。網上的很多例子似乎都暗示async/await我不太理解。它看起來像await需要 aPromise作為參數,但在我的情況下,我正在模擬點擊,它進一步調用返回 a 的處理程序Promise,所以我不能await在那個 axiosPromise上直接完成。這里測試的最佳實踐是什么?
查看完整描述

2 回答

?
忽然笑

TA貢獻1806條經驗 獲得超5個贊

我認為以下方法可以解決問題:


describe('an error occurred while updating', () => {

  beforeEach(() => {});


    it('decrements the counter', async () => {

      const promise = Promise.reject('boo');

      axios.patch.mockImplementationOnce(() => promise);

      const wrapper = mount(

        <MyCoolButton initialCounter={99} />

      );


      // Click the button

      wrapper.find(`.cool-button`).first().simulate('click');

      //do catch().then to make sure test executes after

      //  component caught the rejection.

      return promise.catch(x=>x).then(() => {

        // Check for decrmented value

        const body = wrapper.find('.container span');

        expect(body).to.have.text('Counter value is: 98');

      });

    });

});

以下是一些用于開玩笑的異步示例


查看完整回答
反對 回復 2022-07-08
?
莫回無

TA貢獻1865條經驗 獲得超7個贊

在進行斷言之前,您需要掛載組件并模擬點擊事件:


describe("an error occurred while updating", () => {

  let wrapper;


  beforeEach(() => {

    axios.patch.mockRejectedValue("Mock error message");

    wrapper = mount(<MyCoolButton initialCounter={99} />);

    wrapper.find(".cool-button").simulate("click");

  });


  it("decrements the counter", () => {

    expect(wrapper.find(".container span").text()).toEqual(

      "Counter value is: 98"

    );

  });

});


查看完整回答
反對 回復 2022-07-08
  • 2 回答
  • 0 關注
  • 185 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號