[英]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.