我正在努力寻找一种解决方案,以解决如何用笑话来测试此导出函数的问题。
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
});
});
有人可以给我一些有关如何使用这些依赖项测试代码的提示吗?
答案 0 :(得分:0)
scrollToError()
是异步函数,您无法调用它并期望结果立即存在。在测试之前,您需要等待一段时间的毫秒数(以您的情况为400)。
在Jest:Testing Asynchronous Code中对异步代码进行的测试有所不同。您也可以take control over the timers或将其与manual mocks结合起来并覆盖jQuery本身。
答案 1 :(得分:0)
您如何使用jQuery?
我的意思是,您是使用npm还是yarn获得的?要模拟node_modules,您可以点击以下链接:https://jestjs.io/docs/en/manual-mocks#mocking-node-modules
否则,您将必须创建一个手动模拟。您可以在此处查看操作方法:https://jestjs.io/docs/en/manual-mocks
已更新:
最简单的方法是覆盖它,即以beforeXXX
方法设置测试。
您可以简单地输入类似window.JQuery = jest.fn();
这是有史以来最简单的模拟,但是您将必须创建animate
之类的方法以及其他与jquery相关的方法。
在这里有第二个想法,并期待您的功能,如果您模拟jQuery,还有什么需要测试?
如果进行模拟,则将测试您的fn是否正在执行此处定义的步骤。就像检查jQuery fn是用.has-error
类调用还是animate
是否接收到正确的参数一样。
这种测试根本无法帮助您,只是检查您的算法是否逐行执行。这里的问题是,您可以进行一些重构,例如通过其他改进的类来更改.has-error
类名或animate方法。
您真正需要更改的内容,如果最终要执行的操作。显示div或应显示的任何内容。如果您进行测试,则无论您采用何种方式重构代码,测试都将检查最终解决方案是否仍然有效以及有什么意义。
我清除了吗?英语不是我的母语,所以可能有点混乱
答案 2 :(得分:0)
我终于设法找到合适的解决方案。 我为此写了三个测试用例:
jest.useFakeTimers();
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,以便它运行而无需等待延迟。我还用所需的适当详细信息模拟了html。
最后,我只讨论另一种情况。
PS::我在scrollToError方法中添加了return true
语句,以使其更容易获得预期的结果。
通过这种方法,我达到了100%的覆盖率。