简体   繁体   English

酶异步等待模拟函数未被调用

[英]Enzyme async await mock function not being called

I'm trying to test an async await function, however im getting an error.我正在尝试测试异步等待函数,但是我收到错误消息。

● Should handle getGIF event › should handle getGIF event ● 应该处理 getGIF 事件 › 应该处理 getGIF 事件

expect(jest.fn()).toHaveBeenCalledTimes(1) Expected mock function to have been called one time, but it was called zero times.

I'm unsure how to test async await functions, so i was using this blog as an example https://medium.com/@rishabhsrao/mocking-and-testing-fetch-with-jest-c4d670e2e167我不确定如何测试异步等待函数,所以我以这个博客为例https://medium.com/@rishabhsrao/mocking-and-testing-fetch-with-jest-c4d670e2e167

App.js应用程序.js

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
import Card from './Card';
import PropTypes from "prop-types";
const Styles = {
    marginTop: '100px',
    inputStyle: {
        borderRadius: '0px',
        border: 'none',
        borderBottom: '2px solid #000',
        outline: 'none',
        focus: 'none'
    }
}
class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            query: '',
            title: undefined,
            url: undefined
        }
        this.onChange = this.onChange.bind(this);
    }
    onChange(e) {
        this.setState({query: e.target.value})
    }
    // testing this function 
    getGIY = async(e) => {
        e.preventDefault();
        const { query } = this.state;
        await fetch(`http://api.giphy.com/v1/gifs/search?q=${query}&api_key=iBXhsCDYcnktw8n3WSJvIUQCXRqVv8AP&limit=5`)
        .then(response => response.json())
        .then(({ data }) => {
          this.setState({
            title: data[0].title,
            url: data[0].images.downsized.url
          });
        })
        .catch( (err) =>{
            console.log(err)
        });

    }
    render() {
        return (
            <div className="col-md-6 mx-auto" style={Styles}>
                <h1 className="gif-title">Random GIF fetch</h1>
                <form className="form-group" onSubmit={this.getGIY}>
                    <input
                        style={Styles.inputStyle}
                        className="form-control"
                        type="text"
                        value={this.state.query}
                        onChange={this.onChange}
                        placeholder="Search GIF..."/>
                    <button type="submit" className="btn btn-primary mt-4">Get GIF</button>
                </form>
                <Card title={this.state.title} url={this.state.url}/>
            </div>
        );
    }
}
PropTypes.propTypes = {
    onChange: PropTypes.func.isRequired,
    getGIY:PropTypes.func.isRequired,
    title:PropTypes.string.isRequired,
    url:PropTypes.string.isRequired
}
export default App;

App.test.js App.test.js

import React from 'react';
import ReactDOM from 'react-dom';
import {shallow} from 'enzyme';
import App from './App';



describe('Should handle getGIF event', ()=> {
  it('should handle getGIF event', done => {
    const component = shallow(<App/>)

    const mockSuccessResponse = {};
    const mockJsonPromise = Promise.resolve(mockSuccessResponse);
    const mockQuery = "Owl"

    const mockFetchPromise = Promise.resolve({
      json:() => mockJsonPromise,

    });
    jest.spyOn(global, 'fetch').mockImplementation(()=> mockFetchPromise);

    expect(global.fetch).toHaveBeenCalledTimes(1);
    expect(global.fetch).toHaveBeenCalledWith(`http://api.giphy.com/v1/gifs/search?q=${mockQuery}&api_key=iBXhsCDYcnktw8n3WSJvIUQCXRqVv8AP&limit=5`);

    process.nextTick(() => { // 6
      expect(component.state()).toEqual({
        // ... assert the set state
      });

      global.fetch.mockClear(); // 7
      done(); // 8
    });

  })
})

You can test it like this:你可以这样测试:

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

describe('Should handle getGIF event', () => {

  let mock, actualFetch;
  beforeEach(() => {
    mock = jest.fn();
    actualFetch = global.fetch;
    global.fetch = mock;
  });
  afterEach(() => {
    global.fetch = actualFetch;
  });

  it('should handle getGIF event', async () => {
    const component = shallow(<App />);
    component.setState({ query: 'Owl' });
    mock.mockResolvedValue({ 
      json: () => Promise.resolve({
        data: [{
          title: 'the title',
          images: { downsized: { url: 'the url' }}
        }]
      })
    });
    const form = component.find('form');

    await form.props().onSubmit({ preventDefault: () => {} });

    expect(mock).toHaveBeenCalledWith('http://api.giphy.com/v1/gifs/search?q=Owl&api_key=iBXhsCDYcnktw8n3WSJvIUQCXRqVv8AP&limit=5');  // Success!
    expect(component.state('title')).toBe('the title');  // Success!
    expect(component.state('url')).toBe('the url');  // Success!
  });
});

Details细节

fetch might not be defined in a Node.js environment so just grabbing whatever it was and replacing it with a mock, then restoring whatever it was is a good approach. fetch可能没有在 Node.js 环境中定义,所以只要抓取它是什么并用模拟替换它,然后恢复它是一个很好的方法。

Use .setState to set the component state.使用.setState设置组件状态。

Use .find to get the form and use .props to access its props and call its onSubmit function.使用.find获取form并使用.props访问其道具并调用其onSubmit函数。

Use an async test function and await the Promise returned by onSubmit so it is completely done before continuing.使用async测试函数并await onSubmit返回的Promise以便在继续之前完全完成。

Use .state to query the component state.使用.state查询组件状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM