簡體   English   中英

我可以監視 object 而不是 object 方法嗎?

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

我知道當我引用 object 時,我可以使用如下所示的 spy 來跟蹤調用 function 的次數。

jest.spyOn(myObj, 'myFunc')

但是,當我引用了我想使用的 function 時,我該怎么辦? jest.spyOn(myFunc)不起作用

為了澄清,我想使用 function 的實際實現。 我只是想看看它被調用了多少次以及使用了哪個 arguments。

當我嘗試在普通的 function 上看到這些東西時,我得到:

  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。您可以使用jest.mock和實際實現來模擬fetch function。 而且,我們可以在實現中添加一個間諜。 您可以為該間諜做出斷言。

例如

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 function 創建一個代理。

代理 object 使您能夠為另一個 object 創建代理,它可以攔截和重新定義該 object 的基本操作。

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

這兩種方法本質上是一樣的。 核心思想是使用代理、攔截器、高階function

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM