typescript - ts-jest:模拟内部模块
问题描述
我有一个以下.ts
模块
import client from './client';
export default class DefaultRequest implements IRequest {
make(req: Request): Promise<Response> {
return new Promise<Response>((resolve, reject) => {
client.post(req, (error: Error | null, res: Response) => {
if (error) {
return reject(error);
} else {
return resolve(res);
}
});
});
}
}
我正在尝试用 为这个类编写一个单元测试ts-jest
,所以它client
被嘲笑(并返回一些有效的Response
)。
这是我的做法:
import {mocked} from 'ts-jest/utils';
import client from './client';
import DefaultRequest from './request'
const mockedClient = mocked(client, true);
const testRequest = new DefaultRequest();
jest.mock('./client', () => {
return {
RestClient: jest.fn().mockImplementation(() => {
return {
post: () => {return someValidResponse();},
};
})
};
});
describe('My Tests', () => {
it('Unit Test 1', async () => {
let res: Response = await testRequest.make(buildReq());
});
});
但是 mockedClient 仍然没有被嘲笑。这./client.ts
看起来像:
import { RestClient } from '@rest/client';
export default new RestClient();
可以用这种方式client
模拟类使用的内部模块吗?DefaultRequest
编辑:我也试过jest.spyOn
const spiedMethod= jest.spyOn(client, 'post');
const call: Request = new Request();
const response: Response = await call.make(buildRequest());
expect(spiedReleaseMethod).toHaveBeenCalled();
expect(response.getResponsecode()).toBe(200);
它仍然调用原始方法而不是间谍方法。
解决方案
您正在测试request.ts
依赖于模块的client.ts
模块。所以你需要模拟client.ts
模块及其post
方法而不是@rest/client
包。
例如
request.ts
:
import client from './client';
interface IRequest {
make(req: Request): Promise<Response>;
}
export default class DefaultRequest implements IRequest {
make(req: Request): Promise<Response> {
return new Promise<Response>((resolve, reject) => {
client.post(req, (error: Error | null, res: Response) => {
if (error) {
return reject(error);
} else {
return resolve(res);
}
});
});
}
}
client.ts
:(不管客户端使用什么包实现,只要模块暴露的接口是一样的)
export default {
post(req, callback) {
console.log('real implementation');
},
};
request.test.ts
:
import { mocked } from 'ts-jest/utils';
import client from './client';
import DefaultRequest from './request';
jest.mock('./client');
const mockedClient = mocked(client);
describe('68115300', () => {
afterAll(() => {
jest.resetAllMocks();
});
it('should pass', () => {
mockedClient.post.mockImplementationOnce((req, callback) => {
callback(null, 'mocked response');
});
const testRequest = new DefaultRequest();
testRequest.make(('req' as unknown) as Request);
expect(mockedClient.post).toBeCalledWith('req', expect.any(Function));
});
});
测试结果:
PASS examples/68115300/request.test.ts (12.448 s)
68115300
✓ should pass (3 ms)
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 77.78 | 50 | 75 | 77.78 |
client.ts | 50 | 100 | 0 | 50 | 3
request.ts | 85.71 | 50 | 100 | 85.71 | 12
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 14.61 s
推荐阅读
- php - yii2、kartik fileinput、ajax上传场景:上传第二个文件、第三个文件等,错误替换之前文件的标签
- assembly - 汇编中的多位加法
- c - 从 UINT16 到 UINT8 提取和组合位的更快方法
- python - 在 matplotlib 中为检查按钮文本着色
- mysql - Hibernate 返回最后一行 n 次
- robotframework - 已超出启动关键字的最大限制
- google-cloud-platform - 删除 gcs 冗余 gcs 存储桶
- javascript - 如何在javascript文件中提取数据库内容
- python - 如何在Python中获取包含多个单词的所有句子
- macos - macOS 上的多个网络扩展