Unit testing 使用jest截取函数

Unit testing 使用jest截取函数,unit-testing,mocking,jestjs,sinon,Unit Testing,Mocking,Jestjs,Sinon,有没有一种使用jest API存根函数的方法? 我习惯于使用sinon存根,在这里,我可以用存根编写单元测试,用于测试单元中的任何函数调用- 比如说- sinon.stub(jQuery, "ajax").yieldsTo("success", [1, 2, 3]); Jest Jest.fn(),它具有一些基本的模拟和存根功能 如果您对sinon有经验且熟悉,您仍然可以创建基于笑话的测试,使用sinon测试双打。但是,您将失去内置Jest匹配器的便利性,例如expect(myStubFun

有没有一种使用jest API存根函数的方法? 我习惯于使用sinon存根,在这里,我可以用存根编写单元测试,用于测试单元中的任何函数调用-

比如说-

sinon.stub(jQuery, "ajax").yieldsTo("success", [1, 2, 3]);
Jest Jest.fn(),它具有一些基本的模拟和存根功能


如果您对sinon有经验且熟悉,您仍然可以创建基于笑话的测试,使用sinon测试双打。但是,您将失去内置Jest匹配器的便利性,例如
expect(myStubFunction)。要使用
Jest调用()

,您应该使用:

完整示例:

const spy = jest.fn();
const payload = [1, 2, 3];

jest
  .spyOn(jQuery, "ajax")
  .mockImplementation(({ success }) => success(payload));

jQuery.ajax({
  url: "https://example.api",
  success: data => spy(data)
});

expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith(payload);

您可以在
codesandbox
上尝试实时示例:

我可以使用
mockReturnValue
和jquery的
$.Deferred
完全细分jquery。这使我能够手动解析ajax调用,然后函数的其余部分将继续(并执行
.done()
.success()
等的任何链接)

例如:

const deferred = new $.Deferred();
$.ajax = jest.fn().mockReturnValue(deferred);

myClass.executeAjaxFunction();

const return_val = 7;

deferred.resolve(return_val)
如果我有一个函数,比如

$.ajax({
    type: 'GET',
    url: '/myurl'
}).done((val) => {
    window.property = val;
});
以下测试将通过

it('should set my property correctly', () => {
    expect(window.property).toBe(7);
});

当然,如果你试图存根一个非jquery函数,你可以跳过这个答案的延迟部分。我遇到了这个关于ajax的问题,并提出了这个解决方案,作为一种测试函数的方法,该函数在ajax调用完成后使用
Jest

执行以下两件事,让它为m工作e

  • 添加
    \uu esModule:true
    为我解决了这个问题

    jest.mock('module',()=>({uu-esModule:true,default:jest.fn()}));

  • 将模拟部分移动到“描述”之前。(仅在导入之后。)

    //将其移动到描述之前->
    jest.mock(…);description(“”,…);


  • 希望这对其他人有所帮助。

    谢谢。它可以像sinon.stub.restore那样恢复吗?文档示例对我来说不是很清楚。似乎你只能模拟整个模块,然后模拟其中的func+他们提到了某种自动模拟选项?你发现如何用Jest解决这个问题了吗?你能提供一个示例吗?const spy=Jest.spyOn(jQuery,“ajax”).mockImplementation(({success})=>success(payload));@emj365我刚刚尝试了这种方法,并收到了
    TypeError:success不是一个函数
    。您可以在这里玩它:。只需取消注释12-14行即可。
    it('should set my property correctly', () => {
        expect(window.property).toBe(7);
    });