繁体   English   中英

如何用玩笑模拟回调函数

[英]How to mock callback functions with jest

我正在尝试用 jest 模拟自定义函数,但我遇到了问题。

这是我的功能:

export const resizeImage = (file, fileName, callback) => {
  const MAX_WIDTH = avatarImage.maxWidth;
  const MAX_HEIGHT = avatarImage.maxHeight;
  const img = document.createElement('img');
  img.src = window.URL.createObjectURL(file);
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');

  img.onload = () => {
    const sizes = internalResizeImage(img, MAX_WIDTH, MAX_HEIGHT);

    canvas.width = sizes.width;
    canvas.height = sizes.height;
    ctx.drawImage(img, 0, 0, sizes.width, sizes.height);
    return callback(dataURItoFile(canvas.toDataURL(), fileName));
  };
};

我是这样打电话的:

resizeImage(acceptedFiles[0], this.props.user.id, (res) => {
  //dostuff
});

在我的测试中,我像这样嘲笑它:

let mockResizeImage = jest.fn();

jest.mock('../../utilities/imageUtils', () => ({
  resizeImage: () => mockResizeImage
}));

我希望 mockResizeImage 是一个回调,然后在我的测试中更改返回值:

it('should call handleDrop and accept files', () => {
    //mockResizeImage.mockReturnValue('something');

    const instance = shallow(mockComponent()).instance();
    const acceptFilesMock = ['test'];

    instance.handleDrop(acceptFilesMock);

    expect(clickSpy).toHaveBeenCalledTimes(1);
  });

如果这是一个承诺,一切都很好,但这是一个回调,我不知道我做错了什么。

谢谢。

您可以使用接受与原始参数相同的参数的函数来模拟模块,并立即调用回调:

jest.mock('../../utilities/imageUtils', () => ({
  resizeImage: (file, fileName, callback) => callback('someData')
}));

顺便提一句。 由于jest.mock工作方式,您在问题中模拟模块的方式jest.mock正常工作。 即使你写在let语句之后,在编译测试时也会被提升到文件顶部。 因此,使用 spy 模拟该函数的最佳方法如下所示:

import {resizeImage} from '../../utilities/imageUtils'

jest.mock('../../utilities/imageUtils', () => ({
  resizeImage: jest.fn((file, fileName, callback) => callback('someData'))
}));

现在您的行为与上述相同,但您还可以测试是否使用正确的参数调用了resizeImage

由于您的最后一个参数是一个函数,您可以使用mock.calls测试像这样的第 2 个参数:

expect(resizeImage.mock.calls[0][0]).toBe('firstParameter')
expect(resizeImage.mock.calls[0][1]).toBe('secondParameter')

或者在使用toBeCalledWith使用expect.anything()时对最后一个参数使用通配符:

expect(resizeImage).toBeCalledWith('firstParameter', 'secondParameter', expect.anything()); 

确保当您通过将回调函数作为参数之一传递来调用实际函数时,该函数是从测试块内部调用的,如下所示

function forEach(items, callback) {
  for (let index = 0; index < items.length; index++) {
    callback(items[index]);
  }
}
const mockCallback = jest.fn((x) => x + 1);

test("fn", () => {
  forEach([0, 1, 2], mockCallback);
  expect(mockCallback.mock.calls.length).toBe(3);
});

而不像下面

function forEach(items, callback) {
      for (let index = 0; index < items.length; index++) {
        callback(items[index]);
      }
    }
const mockCallback = jest.fn((x) => x + 1);
forEach([0, 1, 2], mockCallback);
    
test("fn", () => {
   expect(mockCallback.mock.calls.length).toBe(3);
});

暂无
暂无

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

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