在 Typescript Jest 中模拟导出的类

Pan*_*sky 0 unit-testing node.js typescript jestjs

您好,我编写了以下代码来从 Azure Blob 存储中获取 Blob。

import { BlobServiceClient, ContainerClient, ServiceFindBlobsByTagsSegmentResponse } from '@azure/storage-blob';
import { GetBlobPageInput, GetBlobPageOutput, PutBlobItemsInput, GetBlobItem } from './interfaces/blob.service.interface';

export const getBlobsPage = async<T>(input: GetBlobPageInput) => {
  const blobServiceClient = BlobServiceClient.fromConnectionString(input.blobConnectionString);

  const iterator = blobServiceClient
  .findBlobsByTags(input.condition)
  .byPage({ maxPageSize: input.pageSize });

  return getNextPage<T>({
    iterator,
    blobServiceClient,
    blobContainer: input.blobContainer,
  });
};
[...]
Run Code Online (Sandbox Code Playgroud)

我正在尝试为其编写一个单元测试,但是当我尝试从 @azure/storage-blob 模拟 BlobServiceClient 时遇到了麻烦。我编写了示例测试和模拟,如下所示:

import { getBlobsPage } from './../../services/blob.service';

const fromConnectionStringMock = jest.fn();
jest.mock('@azure/storage-blob', () => ({
  BlobServiceClient: jest.fn().mockImplementation(() => ({
    fromConnectionString: fromConnectionStringMock,
  })),
}));

describe('BLOB service tests', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('should fetch first page and return function to get next', async () => {
    const input = {
      blobConnectionString: 'testConnectionString',
      blobContainer: 'testContainer',
      condition: "ATTRIBUTE = 'test'",
      pageSize: 1,
    };

    const result = await getBlobsPage(input);

    expect(fromConnectionStringMock).toHaveBeenCalledTimes(1);
  });
});
Run Code Online (Sandbox Code Playgroud)

但是当我尝试运行测试时我得到:

 TypeError: storage_blob_1.BlobServiceClient.fromConnectionString is not a function

      24 | 
      25 | export const getBlobsPage = async<T>(input: GetBlobPageInput) => {
    > 26 |   const blobServiceClient = BlobServiceClient.fromConnectionString(input.blobConnectionString);
         |                                               ^
      27 | 
      28 |   const iterator = blobServiceClient
      29 |   .findBlobsByTags(input.condition)

      at nhsdIntegration/services/blob.service.ts:26:47
      at nhsdIntegration/services/blob.service.ts:1854:40
      at Object.<anonymous>.__awaiter (nhsdIntegration/services/blob.service.ts:1797:10)
      at Object.getBlobsPage (nhsdIntegration/services/blob.service.ts:25:65)
      at tests/services/blob.service.test.ts:27:26
      at tests/services/blob.service.test.ts:8:71
Run Code Online (Sandbox Code Playgroud)

关于如何正确实现azure模块的模拟有什么建议吗?

我尝试在 StackOverflow 上遵循几个不同的答案,并浏览网络上的文章(例如: https: //dev.to/codedivoire/how-to-mock-an-imported-typescript-class-with-jest-2g7j)。他们中的大多数人都表明这是正确的解决方案,所以我想我在这里遗漏了一些小东西,但无法弄清楚。

tmh*_*005 5

导出的BlobServiceClient应该是一个文字对象,但您现在将其嘲笑为函数,这就是问题所在。

因此,您可能需要简单地模拟返回一个文字对象。另一个问题是从模拟范围之外访问 varfromConnectionStringMock会导致另一个问题。

所以这可能是正确的模拟:

jest.mock('@azure/storage-blob', () => ({
  ...jest.requireActual('@azure/storage-blob'), // keep other props as they are
  BlobServiceClient: {
    fromConnectionString: jest.fn().mockReturnValue({
      findBlobsByTags: jest.fn().mockReturnValue({
        byPage: jest.fn(),
      }),
    }),
  },
}));

Run Code Online (Sandbox Code Playgroud)