在 Jest 中,如何模拟具有依赖项的 TypeScript 类?

Jef*_*Wen 5 typescript jestjs ts-jest

考虑到这个相对人为的类从 Elasticsearch(或任何与此相关的数据存储)获取一条记录:

export default class UserRepoImpl implements UserRepo {
  constructor(private readonly esClient: ElasticsearchClient) {}

  public async getUser(id: string): Promise<User> {
    const response = await this.esClient.request('GET', `/users/_doc/${id}`);

    return response._source;
  }
}

Run Code Online (Sandbox Code Playgroud)

如何编写一个测试来UserRepoImpl为我实例化 a 但插入一个模拟的 ElasticsearchClient作为构造函数的参数?

sli*_*wp2 2

这是单元测试解决方案:

\n

userRepoImpl.ts

\n
interface User {}\ninterface UserRepo {\n  getUser(id: string): Promise<User>;\n}\ninterface ElasticsearchClient {\n  request(method: string, endpoint: string): Promise<{ _source: any }>;\n}\nexport default class UserRepoImpl implements UserRepo {\n  constructor(private readonly esClient: ElasticsearchClient) {}\n\n  public async getUser(id: string): Promise<User> {\n    const response = await this.esClient.request(\'GET\', `/users/_doc/${id}`);\n\n    return response._source;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

userRepoImpl.test.ts

\n
import UserRepoImpl from \'./userRepoImpl\';\n\ndescribe(\'62603645\', () => {\n  it(\'should pass\', async () => {\n    const mUser = { name: \'wen\' };\n    const mEsClient = { request: jest.fn().mockResolvedValueOnce({ _source: mUser }) };\n    const userRepoImpl = new UserRepoImpl(mEsClient);\n    const actual = await userRepoImpl.getUser(\'1\');\n    expect(actual).toEqual(mUser);\n    expect(mEsClient.request).toBeCalledWith(\'GET\', \'/users/_doc/1\');\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

带有覆盖率报告的单元测试结果:

\n
 PASS  stackoverflow/62603645/userRepoImpl.test.ts (10.988s)\n  62603645\n    \xe2\x9c\x93 should pass (5ms)\n\n-----------------|---------|----------|---------|---------|-------------------\nFile             | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n-----------------|---------|----------|---------|---------|-------------------\nAll files        |     100 |      100 |     100 |     100 |                   \n userRepoImpl.ts |     100 |      100 |     100 |     100 |                   \n-----------------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        12.27s\n
Run Code Online (Sandbox Code Playgroud)\n