簡體   English   中英

在 Jest 中,您如何模擬具有依賴關系的 TypeScript class ?

[英]In Jest, how do you mock a TypeScript class with dependencies?

鑒於這個相對做作的 class 從 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;
  }
}

如何編寫一個測試來為我實例化一個UserRepoImpl但插入一個模擬的ElasticsearchClient作為構造函數的參數?

這是單元測試解決方案:

userRepoImpl.ts

interface User {}
interface UserRepo {
  getUser(id: string): Promise<User>;
}
interface ElasticsearchClient {
  request(method: string, endpoint: string): Promise<{ _source: any }>;
}
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;
  }
}

userRepoImpl.test.ts

import UserRepoImpl from './userRepoImpl';

describe('62603645', () => {
  it('should pass', async () => {
    const mUser = { name: 'wen' };
    const mEsClient = { request: jest.fn().mockResolvedValueOnce({ _source: mUser }) };
    const userRepoImpl = new UserRepoImpl(mEsClient);
    const actual = await userRepoImpl.getUser('1');
    expect(actual).toEqual(mUser);
    expect(mEsClient.request).toBeCalledWith('GET', '/users/_doc/1');
  });
});

帶有覆蓋率報告的單元測試結果:

 PASS  stackoverflow/62603645/userRepoImpl.test.ts (10.988s)
  62603645
    ✓ should pass (5ms)

-----------------|---------|----------|---------|---------|-------------------
File             | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------------|---------|----------|---------|---------|-------------------
All files        |     100 |      100 |     100 |     100 |                   
 userRepoImpl.ts |     100 |      100 |     100 |     100 |                   
-----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        12.27s

您可以像這樣在測試中創建模擬客戶端:

const client: jest.Mocked<ElasticsearchClient> = {
  request: jest.fn()
}

它將在傳遞時靜態檢查解析值的類型:

示例測試:

describe('UserRepoImpl', () => {
  describe('given a client', () => {
    const client: jest.Mocked<ElasticsearchClient> = {
      request: jest.fn()
    }
    describe('getUser', () => {
      beforeAll(() => {
        client.request.mockResolvedValue({
          _source: {
            id: '3'
          }
        })
      })

      it('should return user by Id', async () => {
        const userRepo = new UserRepoImpl(client)
        await expect(userRepo.getUser("3")).resolves.toEqual({
          id: '3'
        })
      })
    })
  })
})

暫無
暫無

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

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