[英]How to mock callback functions with jest
I'm trying to mock a custom function with jest but I'm having problems with it.我正在尝试用 jest 模拟自定义函数,但我遇到了问题。
This is my function:这是我的功能:
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));
};
};
I called like this:我是这样打电话的:
resizeImage(acceptedFiles[0], this.props.user.id, (res) => {
//dostuff
});
In my test I'm mocking it like this:在我的测试中,我像这样嘲笑它:
let mockResizeImage = jest.fn();
jest.mock('../../utilities/imageUtils', () => ({
resizeImage: () => mockResizeImage
}));
I want mockResizeImage to be a callback and then in my test change the returning values:我希望 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);
});
If it were a promise, all good, but it's a callback and I don't know what I'm doing wrong.如果这是一个承诺,一切都很好,但这是一个回调,我不知道我做错了什么。
Thanks.谢谢。
You can mock a module with a function that accepts the same parameter as your original one, and instantly call the callback:您可以使用接受与原始参数相同的参数的函数来模拟模块,并立即调用回调:
jest.mock('../../utilities/imageUtils', () => ({
resizeImage: (file, fileName, callback) => callback('someData')
}));
Btw.顺便提一句。 the way you mock the module in your question can't work because of the way
jest.mock
works.由于
jest.mock
工作方式,您在问题中模拟模块的方式jest.mock
正常工作。 Even if you write it after the let
statement, it will be hoisted to the top of the file when the test is been compiled.即使你写在
let
语句之后,在编译测试时也会被提升到文件顶部。 So the best way to mock the function with a spy would look like this:因此,使用 spy 模拟该函数的最佳方法如下所示:
import {resizeImage} from '../../utilities/imageUtils'
jest.mock('../../utilities/imageUtils', () => ({
resizeImage: jest.fn((file, fileName, callback) => callback('someData'))
}));
Now you have the same behaviour as above but you can also test that resizeImage
was called with the correct parameters.现在您的行为与上述相同,但您还可以测试是否使用正确的参数调用了
resizeImage
。
As your last parameter is a function you can either just test for the 2 first params like this using mock.calls
:由于您的最后一个参数是一个函数,您可以使用
mock.calls
测试像这样的第 2 个参数:
expect(resizeImage.mock.calls[0][0]).toBe('firstParameter')
expect(resizeImage.mock.calls[0][1]).toBe('secondParameter')
Or use a wildcard for the last parameter when using toBeCalledWith
using expect.anything()
:或者在使用
toBeCalledWith
使用expect.anything()
时对最后一个参数使用通配符:
expect(resizeImage).toBeCalledWith('firstParameter', 'secondParameter', expect.anything());
Make sure when you call the actual function by passing the callback function as one of the arguments, that function is being called from inside the test block like below确保当您通过将回调函数作为参数之一传递来调用实际函数时,该函数是从测试块内部调用的,如下所示
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);
});
And not like below而不像下面
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.