在 Typescript 的函数中模拟获取
Mock fetch within a function in Typescript
我是打字稿的新手,如果这是微不足道的,请提前致歉。
我有一个像这样在内部使用 Fetch 的函数
export class MyClass {
classVar1: string;
classVar2: string;
...
async postEvent(event: eventSchema) {
const headers = {
'Content-type': 'application/json',
'Api-Key': 'APIKEY}',
};
let result = null;
const response = await fetch('url', {
method: 'POST',
body: event,
headers: headers,
});
result = await response;
return result;
}
}
我正在尝试测试 postEvent 方法,为此我试图仅模拟获取部分。
但无论我如何处理,实际的方法仍然是被调用的方法。
根据我在网上找到的内容,这就是我的 .spec.ts 文件
中的内容
import { MyClass } from './my-class';
import fetch from 'node-fetch';
jest.mock('node-fetch');
describe('My class mocked fetch', () => {
beforeEach(() => {
(MyClass as any).postEvent = jest.fn();
(fetch as any) = jest.fn().mockResolvedValue({
url: 'url',
status: 200,
statusText: 'OK',
counter: 0,
});
});
it('Calls mockedFetch and gets the mocked values', async () => {
expect(fetch).toHaveBeenCalledTimes(0);
const response = await myClass.postEvent('testMsg')
console.log('RESPONSE', response)
});
在最后一行 (console.log('RESPONSE', response)),我希望看到 mockResolved 值,即
url: 'url',
status: 200,
statusText: 'OK',
counter: 0,
但它 returns 无论实际提取将生成什么。
有人可以帮忙吗?
p.s 我也阅读了有关 spyOn 方法的信息,但我无法找到适合我上述用例的打字稿示例。
有一个这样的 JS 例子
const fetchMock = jest.spyOn(global, 'fetch').mockImplementation(() => Promise.resolve({ json: () => Promise.resolve([]) }))
但是如果像下面这样在类型脚本中使用它会抛出异常
'Promise<{ json: () => Promise<any[]>; }>' is not assignable to type 'Promise<Response>'.
你的测试有一些问题,我会一一解释。
您想测试 MyClass
的 postEvent
方法,那么您应该 而不是 将其替换为 jest.fn()
创建的模拟函数.
如果 fetch
函数来自 node-fetch
,那么您应该模拟 node-fetch
模块而不是 global.fetch
。
在我们使用 jest.mock('node-fetch')
模拟 node-fetch
之后,jest 会自动为 node-fetch
公开的每个成员创建模拟对象。
node-fetch
导出 Response class,我们可以用它来创建模拟响应。但是前面说过,jest.mock()
已经创建了Response
class的mocked版本,我们如何得到原来的Response
class?
jest.requireActual(moduleName) 可以帮助我们,它 returns 实际模块而不是模拟。
综上所述,完整的测试代码如下:
my-class.ts
:
import fetch from 'node-fetch';
export class MyClass {
async postEvent(event) {
const headers = {
'Content-type': 'application/json',
'Api-Key': 'APIKEY',
};
const response = await fetch('url', {
method: 'POST',
body: event,
headers: headers,
});
return response.json();
}
}
index.test.ts
:
import { MyClass } from './my-class';
import fetch from 'node-fetch';
jest.mock('node-fetch');
const { Response } = jest.requireActual('node-fetch');
describe('69579937', () => {
it('Calls mockedFetch and gets the mocked values', async () => {
expect(fetch).toHaveBeenCalledTimes(0);
(fetch as jest.MockedFunction<typeof fetch>).mockResolvedValue(
new Response(JSON.stringify({ name: 'teresa teng' }), { url: 'url', status: 200, statusText: 'OK' })
);
const myclass = new MyClass();
const response = await myclass.postEvent('testMsg');
expect(response).toEqual({ name: 'teresa teng' });
});
});
测试结果:
PASS examples/69579937/my-class.test.ts
69579937
✓ Calls mockedFetch and gets the mocked values (3 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.893 s, estimated 11 s
Ran all test suites related to changed files.
我是打字稿的新手,如果这是微不足道的,请提前致歉。 我有一个像这样在内部使用 Fetch 的函数
export class MyClass {
classVar1: string;
classVar2: string;
...
async postEvent(event: eventSchema) {
const headers = {
'Content-type': 'application/json',
'Api-Key': 'APIKEY}',
};
let result = null;
const response = await fetch('url', {
method: 'POST',
body: event,
headers: headers,
});
result = await response;
return result;
}
}
我正在尝试测试 postEvent 方法,为此我试图仅模拟获取部分。 但无论我如何处理,实际的方法仍然是被调用的方法。 根据我在网上找到的内容,这就是我的 .spec.ts 文件
中的内容import { MyClass } from './my-class';
import fetch from 'node-fetch';
jest.mock('node-fetch');
describe('My class mocked fetch', () => {
beforeEach(() => {
(MyClass as any).postEvent = jest.fn();
(fetch as any) = jest.fn().mockResolvedValue({
url: 'url',
status: 200,
statusText: 'OK',
counter: 0,
});
});
it('Calls mockedFetch and gets the mocked values', async () => {
expect(fetch).toHaveBeenCalledTimes(0);
const response = await myClass.postEvent('testMsg')
console.log('RESPONSE', response)
});
在最后一行 (console.log('RESPONSE', response)),我希望看到 mockResolved 值,即
url: 'url',
status: 200,
statusText: 'OK',
counter: 0,
但它 returns 无论实际提取将生成什么。
有人可以帮忙吗?
p.s 我也阅读了有关 spyOn 方法的信息,但我无法找到适合我上述用例的打字稿示例。 有一个这样的 JS 例子
const fetchMock = jest.spyOn(global, 'fetch').mockImplementation(() => Promise.resolve({ json: () => Promise.resolve([]) }))
但是如果像下面这样在类型脚本中使用它会抛出异常
'Promise<{ json: () => Promise<any[]>; }>' is not assignable to type 'Promise<Response>'.
你的测试有一些问题,我会一一解释。
您想测试 MyClass
的 postEvent
方法,那么您应该 而不是 将其替换为 jest.fn()
创建的模拟函数.
如果 fetch
函数来自 node-fetch
,那么您应该模拟 node-fetch
模块而不是 global.fetch
。
在我们使用 jest.mock('node-fetch')
模拟 node-fetch
之后,jest 会自动为 node-fetch
公开的每个成员创建模拟对象。
node-fetch
导出 Response class,我们可以用它来创建模拟响应。但是前面说过,jest.mock()
已经创建了Response
class的mocked版本,我们如何得到原来的Response
class?
jest.requireActual(moduleName) 可以帮助我们,它 returns 实际模块而不是模拟。
综上所述,完整的测试代码如下:
my-class.ts
:
import fetch from 'node-fetch';
export class MyClass {
async postEvent(event) {
const headers = {
'Content-type': 'application/json',
'Api-Key': 'APIKEY',
};
const response = await fetch('url', {
method: 'POST',
body: event,
headers: headers,
});
return response.json();
}
}
index.test.ts
:
import { MyClass } from './my-class';
import fetch from 'node-fetch';
jest.mock('node-fetch');
const { Response } = jest.requireActual('node-fetch');
describe('69579937', () => {
it('Calls mockedFetch and gets the mocked values', async () => {
expect(fetch).toHaveBeenCalledTimes(0);
(fetch as jest.MockedFunction<typeof fetch>).mockResolvedValue(
new Response(JSON.stringify({ name: 'teresa teng' }), { url: 'url', status: 200, statusText: 'OK' })
);
const myclass = new MyClass();
const response = await myclass.postEvent('testMsg');
expect(response).toEqual({ name: 'teresa teng' });
});
});
测试结果:
PASS examples/69579937/my-class.test.ts
69579937
✓ Calls mockedFetch and gets the mocked values (3 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.893 s, estimated 11 s
Ran all test suites related to changed files.