如何用笑话测试此方法

时间:2019-02-13 19:35:36

标签: javascript unit-testing jestjs

我正在努力寻找一种解决方案,以解决如何用笑话来测试此导出函数的问题。

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 
  });
});

有人可以给我一些有关如何使用这些依赖项测试代码的提示吗?

3 个答案:

答案 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%的覆盖率。