简体   繁体   English

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

[英]Can I spy on an object rather than an object method?

I know that I can use spy like below to track the number of times a function has been called, when I have a reference to the object on which it is a method.我知道当我引用 object 时,我可以使用如下所示的 spy 来跟踪调用 function 的次数。

jest.spyOn(myObj, 'myFunc')

But what do I do when I have a reference to the function that I want to use?但是,当我引用了我想使用的 function 时,我该怎么办? jest.spyOn(myFunc) does not work jest.spyOn(myFunc)不起作用

To clarify, I want to use the real implementation of the function.为了澄清,我想使用 function 的实际实现。 I just want to be able to see how many times it has been called and with which arguments.我只是想看看它被调用了多少次以及使用了哪个 arguments。

When I try to see those things on an ordinary function I get:当我尝试在普通的 function 上看到这些东西时,我得到:

  expect(received).toHaveBeenCalledWith(...expected)
Matcher error: received value must be a mock or spy function

Here is (most of) the actual test:这是(大部分)实际测试:

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

Option 1. You can mock the fetch function using jest.mock with the real implementation.选项 1。您可以使用jest.mock和实际实现来模拟fetch function。 And, we can add a spy in the implementation.而且,我们可以在实现中添加一个间谍。 You can make assertions for that spy.您可以为该间谍做出断言。

Eg例如

fetch.ts : fetch.ts

export async function fetch(name) {
  return 'real implementation';
}

fetch.test.ts : 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);
  });
});

test result:测试结果:

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

Option 2. You can use Proxy to create a proxy for your fetch function.选项 2。您可以使用Proxy为您的fetch function 创建一个代理。

The Proxy object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object.代理 object 使您能够为另一个 object 创建代理,它可以拦截和重新定义该 object 的基本操作。

fetch-v2.test.ts : 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);
  });
});

test result:测试结果:

 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

The two methods are essentially the same.这两种方法本质上是一样的。 The core idea is to use proxy, interceptor, high order function核心思想是使用代理、拦截器、高阶function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 笑话:窥探 object 方法? - Jest: Spy on object method? 如何在 Node.js 的 console.log() 中获取完整的 object,而不是“[Object]”? - How can I get the full object in Node.js's console.log(), rather than '[Object]'? 用方法扩展jQuery,但返回该方法而不是jQuery对象 - Extend jQuery with method, but return that method rather than jQuery object (js)将整个对象传递给onclick方法而不是字符串 - (js) passing whole object into onclick method rather than a string 如何发送 json object javascript 可以理解为数组而不是使用 ZE1E1D3D40573127E9EE0480CAFZ12 和管道工的字符串? - How do I send json object that javascript can understand as array rather than string using R and plumber? 如何使用参数的值数组构造对象,而不是在JavaScript中列出它们? - How can I construct an object using an array of values for parameters, rather than listing them out, in JavaScript? 任何方式我都可以声明事件 object 而不是在 function 的参数中? - Any way I can declare the event object rather than in the params of a function? 动态获取对象的间谍方法 - Spy method from dynamically obtained object 茉莉花:如何监视内部对象方法调用? - Jasmine: how to spy on inner object method call? 如何使Transcrypt编译为对象而不是dict? - How can one make Transcrypt compile to object rather than dict?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM