Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

node.js - Mock exported class in Typescript Jest

Hi i wrote following code to fetch blobs from Azure Blob Storage.

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,
  });
};
[...]

I am trying to write a unit test for it, but i have trouble when i try to mock BlobServiceClient from @azure/storage-blob. I wrote sample test and mock as this:

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);
  });
});

But when i try to run test i am getting:

 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

Any tips on how should I properly implement mock for azure module?

I've tried following several diffrent answers on StackOverflow and looked through articles on web (like: https://dev.to/codedivoire/how-to-mock-an-imported-typescript-class-with-jest-2g7j). And most of them show that this is the proper solution, so i guess i am missing some small thing here but can't figure it out.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The exported BlobServiceClient is supposed to be a literal object but you're now mocking as function which is the issue.

So you might need to simply mock returning a literal object. Another issue is to access a var fromConnectionStringMock from outside of the mock scope would end up with another issue.

So here's possibly the right mock:

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(),
      }),
    }),
  },
}));


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...