为了账号安全,请及时绑定邮箱和手机立即绑定

我可以监视对象而不是对象方法吗?

我可以监视对象而不是对象方法吗?

交互式爱情 2023-11-12 15:22:14
我知道当我引用了一个函数作为方法的对象时,我可以使用像下面这样的间谍来跟踪函数被调用的次数。jest.spyOn(myObj, 'myFunc')但是,当我引用了我想要使用的函数时,我该怎么办?jest.spyOn(myFunc)不起作用为了澄清一下,我想使用该函数的实际实现。我只是想知道它被调用了多少次以及使用了哪些参数。当我尝试在普通函数上查看这些内容时,我得到:  expect(received).toHaveBeenCalledWith(...expected)Matcher error: received value must be a mock or spy function这是(大部分)实际测试:  it('should set createScrollContextImmediately when result is above the maximum return limit', async () => {    // Arrange    ...    // Act    await fetch(imageID, { size: maxSizePerScroll }, ids, { createScrollContextImmediately: false });    // Assert    expect(fetch).toHaveBeenCalledWith(imageID, { size: maxSizePerScroll }, ids, { createScrollContextImmediately: false });    expect(fetch).toHaveBeenCalledWith(imageID, { size: maxSizePerScroll }, ids, { createScrollContextImmediately: true });    expect(fetch).toHaveBeenCalledTimes(2);  });
查看完整描述

1 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

选项 1.您可以使用真实的实现来模拟该fetch函数。jest.mock并且,我们可以在实现中添加一个间谍。你可以为那个间谍做出断言。


例如


fetch.ts:


export async function fetch(name) {

  return 'real implementation';

}

fetch.test.ts:


import { fetch } from './fetch';


const fetchSpy = jest.fn();


jest.mock('./fetch', () => {

  const { fetch } = jest.requireActual('./fetch');

  const fetchWithSpy = jest.fn().mockImplementation((...args) => {

    fetchSpy(...args);

    return fetch(...args);

  });

  return {

    fetch: fetchWithSpy,

  };

});


describe('65266282', () => {

  it('should set createScrollContextImmediately when result is above the maximum return limit', async () => {

    const actual = await fetch('teresa teng');

    expect(actual).toBe('real implementation');

    expect(fetchSpy).toBeCalledWith('teresa teng');

    expect(fetchSpy).toHaveBeenCalledTimes(1);

  });

});

测试结果:


PASS  examples/65266282/fetch.test.ts

  65266282

    ✓ should set createScrollContextImmediately when result is above the maximum return limit (8 ms)


Test Suites: 1 passed, 1 total

Tests:       1 passed, 1 total

Snapshots:   0 total

Time:        4.216 s

选项 2.您可以使用Proxy为您的fetch函数创建代理。


Proxy 对象使您能够为另一个对象创建代理,该代理可以拦截并重新定义该对象的基本操作。


fetch-v2.test.ts:


import { fetch } from './fetch';


const fetchSpy = jest.fn();

const fetchProxy = new Proxy(fetch, {

  apply: (target, thisArg, argumentsList) => {

    fetchSpy.apply(thisArg, argumentsList);

    return target.apply(thisArg, argumentsList);

  },

});


describe('65266282', () => {

  it('should set createScrollContextImmediately when result is above the maximum return limit', async () => {

    const actual1 = await fetchProxy('teresa teng');

    expect(actual1).toBe('real implementation');

    const actual2 = await fetchProxy('best singer');

    expect(actual2).toBe('real implementation');

    expect(fetchSpy).toBeCalledWith('teresa teng');

    expect(fetchSpy).toBeCalledWith('best singer');

    expect(fetchSpy).toHaveBeenCalledTimes(2);

  });

});

测试结果:


 PASS  examples/65266282/fetch-v2.test.ts

  65266282

    ✓ should set createScrollContextImmediately when result is above the maximum return limit (3 ms)


Test Suites: 1 passed, 1 total

Tests:       1 passed, 1 total

Snapshots:   0 total

Time:        4.484 s

这两种方法本质上是相同的。核心思想是使用代理、拦截器、高阶函数


查看完整回答
反对 回复 2023-11-12
  • 1 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信