问题描述
我正在努力寻找一种解决方案,以解决如何用笑话来测试此导出的函数。
export const scrollToError = () => {
setTimeout(() => {
const hasErrorElement = jQuery('.has-error');
if (!hasErrorElement.length) return;
jQuery('html,body').animate({
scrollTop: hasErrorElement.offset().top - 50,
}, 'slow');
}, 400);
};
我将其导入测试文件中并尝试启动它:
import { scrollToError } from './utils';
describe('Utils', () => {
it('should scroll to error', () => {
const result = scrollToError();
expect(result).toBe(true); //added this just to force an error and got result as undefined
});
});
谁能给我有关如何使用这些依赖项测试代码的提示吗?
1楼
scrollToError()
是异步函数,您不能调用它并期望结果立即在那。
在测试之前,您需要等待一定数量的毫秒数(在您的情况下为400)。
在Jest: 有所不同。 您还或将其与结合在一起并覆盖jQuery本身。
2楼
您如何使用jQuery?
我的意思是,您使用npm还是yarn获得了它? 要模拟node_modules,您可以点击以下链接: ://jestjs.io/docs/en/manual-mocks#mocking-node-modules
否则,您将必须创建一个手动模拟。 您可以在此处查看操作方法: :
更新:
最简单的方法是覆盖它,即在beforeXXX
方法中设置测试时。
您可以简单地放入诸如window.JQuery = jest.fn();
类的东西window.JQuery = jest.fn();
这是有史以来最简单的模拟,但是您将不得不创建诸如animate
和其他与jquery相关的方法之类的方法。
在这里有第二个想法,并期待您的功能,如果您模拟jQuery,还有什么要测试?
如果您模拟,则将测试您的fn是否正在执行此处定义的步骤。
就像检查jQuery fn是否使用.has-error
类调用或animate
接收到正确的参数。
这种测试根本没有帮助您,只是检查它是否逐行遵循您的算法。
这里的问题是,您可以进行一些重构,例如通过其他改进的类来更改.has-error
类名或animate方法。
您真正需要更改的是什么,如果最终要做什么。 显示div或应显示的任何内容。 如果您进行测试,则无论重构代码的方式如何,测试都将检查最终解决方案是否仍然有效,以及什么很重要。
我说清楚了吗 英语不是我的母语,所以可能有点混乱
3楼
我终于设法找到合适的解决方案。 我为此编写了三个测试用例:
describe('utils', () => {
afterEach(() => {
document.body.innerHTML = '';
});
it('ScrollToError - should run the settimeout for 400 ms', () => {
scrollToError();
expect(setTimeout).toHaveBeenCalledTimes(1);
expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 400);
});
it('ScrollToError - should scroll to error', () => {
document.body.innerHTML = formStep1ErrorMock;
window.setTimeout = fn => fn();
const result = scrollToError();
expect(result).toBe(true);
});
it('ScrollToError - should do nothing as has no errors', () => {
document.body.innerHTML = formStep1Mock;
window.setTimeout = fn => fn();
const result = scrollToError();
expect(result).toBe(true);
});
});
因此,基本上,首先我检查setTimeout是否以适当的秒数调用(这并不重要)。
然后我通过执行此window.setTimeout = fn => fn();
模拟setTimeout。setTimeout window.setTimeout = fn => fn();
因此它运行时无需等待延迟。
我还用所需的适当详细信息模拟了html。
最后,我只讨论另一种情况。
PS:我在scrollToError方法中添加了return true
语句,以使其更容易获得预期的结果。
这样我就达到了该方法100%的覆盖率。