【问题标题】:Mocking a Typescript Class That Makes External API Calls模拟进行外部 API 调用的 Typescript 类
【发布时间】:2021-06-21 17:00:26
【问题描述】:

所以我做了很多阅读/搜索,但似乎无法弄清楚这一点。

我有一个像这样的打字稿类

import * as Shopify from 'shopify-api-node';
export default class ShopifyService {
  private readonly shopify: Shopify;

  constructor(
    config: Shopify.IPublicShopifyConfig | Shopify.IPrivateShopifyConfig,
  ) {
    this.shopify = new Shopify({ ...config, apiVersion: SHOPIFY_API_VERSION });
  }

  public async getCurrentBulkOperation(): Promise<
    ICurrentBulkOperation | undefined
  > {
    const response = await this.shopify.graphql(bulkOperationStatusQuery);
    return response?.currentBulkOperation;
  }
}

这个类只包含多个调用 graphQL 的函数 (this.shopify.graphql) 并返回结果。

我有另一个名为 polly.ts 的文件

export const pollyWolly = {

   async cons(....) {
         const shopify = new ShopifyService({ accessToken, shopName });
         const m = await shopify.getCurrentBulkOperation();
         // do stuff with m. Ex: get f from m, send f to some queue, etc etc.
   }

}

我正在为 pollyWolly 编写测试。例如,当 cons 运行并且 shopify.getCurrentBulkOperation 返回 null 时,测试可能是 hey,然后确保将消息发送到某个队列等。

我想模拟 shopify.getBulkOperation --> 我不想对 shopify 进行实际的 API 调用...而且我想模拟不同的值。例如,在一个测试用例中,我想想象 getBulkOp 返回 null。在另一个我想想象 getBulkOperation 返回一个具有特定字段等的对象。

我已经阅读了很多 stackoverflow 帖子,很多文章,但似乎无法完全理解。

帮助表示赞赏。

【问题讨论】:

  • 你想测试pollyWolly单元,那么你模拟shopify.getCurrentBulkOperation单元会更好。如果您想测试getCurrentBulkOperation,请模拟shopify.graphql

标签: typescript unit-testing jestjs mocking ts-jest


【解决方案1】:

我们可以使用Mock using module factory parameter模拟es6类,并使用mockFn.mockResolvedValueOnce(value)方法为每个测试用例模拟一次解析值。

例如

shopifyService.ts:

import Shopify from 'shopify-api-node';

const SHOPIFY_API_VERSION = '';
const bulkOperationStatusQuery = ``;

interface ICurrentBulkOperation {}

export default class ShopifyService {
  private readonly shopify: Shopify;

  constructor(config: Shopify.IPublicShopifyConfig | Shopify.IPrivateShopifyConfig) {
    this.shopify = new Shopify({ ...config, apiVersion: SHOPIFY_API_VERSION });
  }

  public async getCurrentBulkOperation(): Promise<ICurrentBulkOperation | undefined> {
    const response = await this.shopify.graphql(bulkOperationStatusQuery);
    return response?.currentBulkOperation;
  }
}

polly.ts:

import ShopifyService from './shopifyService';

export const pollyWolly = {
  async cons(accessToken, shopName) {
    const shopify = new ShopifyService({ accessToken, shopName });
    const m = await shopify.getCurrentBulkOperation();
    return m;
  },
};

polly.test.ts:

import { pollyWolly } from './polly';
import ShopifyService from './shopifyService';

const shopifyService = {
  getCurrentBulkOperation: jest.fn(),
};
jest.mock('./shopifyService', () => {
  return jest.fn(() => shopifyService);
});

describe('66790278', () => {
  const accessToken = '123';
  const shopName = 'teresa teng';
  afterEach(() => {
    jest.clearAllMocks();
  });
  afterAll(() => {
    jest.resetAllMocks();
  });
  it('should return value', async () => {
    shopifyService.getCurrentBulkOperation.mockResolvedValueOnce('fake value');
    const actual = await pollyWolly.cons(accessToken, shopName);
    expect(actual).toEqual('fake value');
    expect(shopifyService.getCurrentBulkOperation).toBeCalledTimes(1);
    expect(ShopifyService).toBeCalledWith({ accessToken, shopName });
  });

  it('should return another value', async () => {
    shopifyService.getCurrentBulkOperation.mockResolvedValueOnce('another fake value');
    const actual = await pollyWolly.cons(accessToken, shopName);
    expect(actual).toEqual('another fake value');
    expect(shopifyService.getCurrentBulkOperation).toBeCalledTimes(1);
    expect(ShopifyService).toBeCalledWith({ accessToken, shopName });
  });
});

测试结果:

 PASS  examples/66790278/polly.test.ts (6.536 s)
  66790278
    ✓ should return value (5 ms)
    ✓ should return another value

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.42 s

【讨论】:

    猜你喜欢
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 2021-02-08
    • 1970-01-01
    • 2022-10-24
    • 1970-01-01
    • 2017-01-11
    相关资源
    最近更新 更多