我正在尝试使用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);
});
如果这是一个承诺,一切都很好,但这是一个回调,我不知道我做错了什么。
感谢。
答案 0 :(得分:9)
你可以用一个接受与原版相同参数的函数来模拟一个模块,并立即调用回调:
jest.mock('../../utilities/imageUtils', () => ({
resizeImage: (file, fileName, callback) => callback('someData')
}));
顺便说一下。由于jest.mock
的工作方式,您在问题中模拟模块的方式无法正常工作。即使您在let
语句之后编写它,它也会在编译测试时被提升到文件的顶部。因此,使用间谍模拟函数的最佳方法如下:
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')
使用expect.anything()
使用toBeCalledWith
时,使用通配符作为最后一个参数:
expect(resizeImage).toBeCalledWith('firstParameter', 'secondParameter', expect.anything());
答案 1 :(得分:1)
确保当您通过将回调函数作为参数之一传递来调用实际函数时,该函数是从测试块内部调用的如下
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);
});