簡體   English   中英

Jest 模擬打字稿依賴

[英]Jest mock typescript dependency

我的 index.ts 文件看起來像這樣

import {IS3Client, S3Client} from './client/S3Client';
const s3: IS3Client = new S3Client();

export async function someFunc(event: any, context: any, callback: any) {

  const x: string = await s3.getFile('a','b');

}

S3Client.ts 看起來像這樣

import * as AWS from 'aws-sdk';

export interface IS3Client {
    getFile(bucketName: string, fileName: string): Promise<any>;
}

export class S3Client implements IS3Client {
    private s3Client: AWS.S3;

    constructor() {
        this.s3Client = new AWS.S3();
    }

    public async getFile(bucketName: string, fileName: string): Promise<any> {
        const params = {
            Bucket: bucketName,
            Key: fileName,
        };
        return (await this.s3Client.getObject(params).promise()).Body.toString();
    }
}

現在我有興趣模擬 getFile 函數以在我測試 index.ts 時返回我想要的內容

我的測試用例看起來像這樣

import {someFunc} from '../src/index';
import { S3Client } from '../src/client/S3Client';

describe("Test Suite", () => {
  beforeAll(()=>{
    jest.mock('../src/client/S3Client');
    const mockedClient: jest.Mocked<S3Client> = new S3Client() as any;
    mockedClient.getFile.mockImplementation(() => Promise.resolve('hello'));
  });
  it("testCase", () => {
    const req = {
      "key" : ["value"]
    };
    someFunc(req, null, null);
  })
});

我收到以下錯誤:

TypeError: mockedClient.getFile.mockImplementation is not a function

不知何故,這看起來比我想象的要困難得多。 有人可以提出建議嗎,提前致謝?

我添加了另一個這樣的課程

import { SecretsManager } from 'aws-sdk';

export default class XUtils {
    private secretsManager: SecretsManager;

    constructor(secretsManager: SecretsManager) {
        this.secretsManager = secretsManager;
    }

    public async getData(urlPrefix: string): Promise<any[]> {
        return ['data'];
    }
}

我的 index.ts 看起來像這樣:

import {IS3Client, S3Client} from './client/S3Client';
import XUtils from './utils/XUtils';
import { SecretsManager } from 'aws-sdk';

const s3: IS3Client = new S3Client();
const secretsManager: SecretsManager = new SecretsManager({ region: process.env.AWS_REGION });
const xUtils: XUtils = new XUtils(secretsManager)

export async function someFunc(event: any, context: any, callback: any) {

  const x: string = await s3.getFile('a','b');
  const y = await xUtils.getData(x);
}

按照您的建議,我將測試用例修改為如下所示:

import {someFunc} from '../src/index';
import { S3Client } from '../src/client/S3Client';
import XUtils from '../utils/XUtils';

jest.mock('../src/client/S3Client', () => {
  const mS3Client = { getFile: jest.fn() };
  return { S3Client: jest.fn(() => mS3Client) };
});

jest.mock('../utils/XUtils', () => {
  const mXUtils = { getData: jest.fn() };
  return { XUtils: jest.fn(() => mXUtils) };
});

describe("Test Suite", () => {
  beforeAll(()=>{
    mockedClient = new S3Client() as any;
    mockedClient.getFile.mockImplementation(() => Promise.resolve('url'));

    mockedXUtils = new XUtils(null) as any;
    mockedXUtils.getData.mockImplementation(() => Promise.resolve(['data']))
  });
  it("testCase", () => {
    const req = {
      "key" : ["value"]
    };
    someFunc(req, null, null);
  })
});

我現在收到錯誤

TypeError: XUtils_1.default is not a constructor

這個問題究竟是什么?

  1. 您不能在函數作用域中使用jest.mock 它應該在模塊范圍內使用。
  2. 您應該在測試用例中為someFunc方法使用async/await

例如

index.ts

import { IS3Client, S3Client } from './s3client';
const s3: IS3Client = new S3Client();

export async function someFunc(event: any, context: any, callback: any) {
  const x: string = await s3.getFile('a', 'b');
}

s3client.ts

import * as AWS from 'aws-sdk';

export interface IS3Client {
  getFile(bucketName: string, fileName: string): Promise<any>;
}

export class S3Client implements IS3Client {
  private s3Client: AWS.S3;

  constructor() {
    this.s3Client = new AWS.S3();
  }

  public async getFile(bucketName: string, fileName: string): Promise<any> {
    const params = {
      Bucket: bucketName,
      Key: fileName,
    };
    return (await this.s3Client.getObject(params).promise()).Body!.toString();
  }
}

index.test.ts

import { someFunc } from './';
import { S3Client } from './s3client';

jest.mock('./s3client', () => {
  const mS3Client = { getFile: jest.fn() };
  return { S3Client: jest.fn(() => mS3Client) };
});

describe('Test Suite', () => {
  let mockedClient: jest.Mocked<S3Client>;
  beforeAll(() => {
    mockedClient = new S3Client() as any;
    mockedClient.getFile.mockImplementation(() => Promise.resolve('hello'));
  });
  it('testCase', async () => {
    const req = {
      key: ['value'],
    };
    await someFunc(req, null, null);
    expect(mockedClient.getFile).toBeCalledWith('a', 'b');
  });
});

100% 覆蓋率的單元測試結果:

 PASS  stackoverflow/60445082/index.test.ts (8.548s)
  Test Suite
    ✓ testCase (6ms)

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

源代碼: https : //github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60445082

暫無
暫無

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

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