在箭头功能上进行测试时,酶onclick间谍toHaveBeenCalled测试不起作用 [英] Enzyme onclick spy toHaveBeenCalled test does not work when testing on arrow function

查看:86
本文介绍了在箭头功能上进行测试时,酶onclick间谍toHaveBeenCalled测试不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何测试子组件onclick。

how can i test the child component onclick.

请参见下面的代码段。

// App.js

import React, {Component, Fragment} from 'react'
import Child from './child'

class App extends Component{

  state = {
    data: null,
    enable: false
  }

  componentDidMount(){
    this.getData()
  }

  getData = async () => {
    const response = await fetch('http://www.example.com');
    const data = await response.json();
    this.setState({
      data
    })
  }

  _handleChildClick = () => {
    this.setState({
      enable: true
    })
  }

  render(){
    const {data, enable} = this.state
    if(!data){
      return (
       <div>
         Loading
       </div>
      )
    }else{
      <Fragment>
        <Child
         handleChildClick={this._handleChildClick}
        />
      </Fragment>
    }
  }
}


export default App


import React from 'react';

const child = () => {
  return(
    <div>
      <button
        className="toggle"
        onClick={props.handleChildClick}
      >
      Toggle
      </button>
    </div>
  )
}

export default child

// App.test.js

import React from 'react';
import {enzyme} from 'enzyme';
import App from './App';

describe("App test cases", () => {
  it('should trigger _handleChildClick', async () => {
    window.fetch = jest.fn().mockImplementation(() => ({
      status: 200,
      json: () => new Promise((resolve, reject) => {
        resolve(
            {
              name: "some data"
            }
        )
      })
    })) 
    const mountWrapper = await mount(<App />)
    setTimeout(() => {
       mountWrapper.update()
             const SpyhandleChildClick = jest.spyOn(mountWrapper.instance(),'_handleChildClick')
      mountWrapper.find('.toggle').simulate('click')
      expect(SpyhandleChildClick).toHaveBeenCalled() // not called 
    },0)
  })
})


推荐答案

考虑。


测试中的异步代码

如果必须在测试中执行异步任务,则必须一直等到异步内容完成。

If you have to do asynchronous tasks in your tests you always have to await until the asynchronous stuff is completed.

setTimeout(() => {
   mountWrapper.update()
         const SpyhandleChildClick = jest.spyOn(mountWrapper.instance(),'_handleChildClick')
  mountWrapper.find('.toggle').simulate('click')
  expect(SpyhandleChildClick).toHaveBeenCalled() // not called 
},0)

在代码中,您有一个超时段。此代码块内的任何测试条件都不会被评估,因为到了评估时,由于aync性质,您的测试会话将已经结束。

Above in your code you have a timeout segment. Any test condition inside this code block will not be evaluated since by the time they are evaluated you 'test session' will already be over due to the aync nature.


使用酶在React中测试箭头功能-forceUpdate()

酶库的问题,您必须在侦查反应组件以锁定该方法后强制更新反应组件。
请关注github问题以获取更多信息: https://github.com/airbnb / enzyme / issues / 365

There seem to be a problem with the enzyme library where you have to force update the react component after spying for it to latch on to the method. Please follow the github issue for more information : https://github.com/airbnb/enzyme/issues/365

我还整理了一下您的测试代码,使其更易于理解!

I also cleaned up your test code a bit to make it more understandable!

// App.test.js

import React from 'react';
import {enzyme} from 'enzyme';
import App from './App';


describe("App test cases", () => {
  it("should trigger _handleChildClick", async () => {
    window.fetch = jest.fn().mockImplementation(() => ({
      status: 200,
      json: () =>
        new Promise((resolve, reject) => {
          resolve({
            name: "some data"
          });
        })
    }));

    const mountWrapper = mount(<App />);
    mountWrapper.update();
    console.log("mountWrapper", mountWrapper.debug()); // showing the loader one

    //[FIX]This code will block and wait for your asynchronous tasks to be completed
    await new Promise(res => setTimeout(() => res(), 0));

    mountWrapper.update();
    console.log("mountWrapper", mountWrapper.debug()); // nothing showing
    expect(mountWrapper.find(".toggle").length).toEqual(1);

    //[FIX]Get a reference from the wrapper and force update after the spyOn call
    const instance = mountWrapper.instance();
    const spy = jest.spyOn(instance, "_handleChildClick");
    instance.forceUpdate();

    mountWrapper.find(".toggle").simulate("click");

    expect(spy).toHaveBeenCalled();
  });
});

实时演示链接:单击浏览器上的测试标签以查看测试结果
https://codesandbox.io/s/mz21kpm37j

Live Demo Link: Click on the 'Tests' tab on the browser to see the test results https://codesandbox.io/s/mz21kpm37j

这篇关于在箭头功能上进行测试时,酶onclick间谍toHaveBeenCalled测试不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆