Search code examples
typescriptmockingjestjsts-jest

When mocking a class in typescript using jest/ts-jest I am getting "TypeError: "X".default is not a constructor."


I am writing a unit test using jest/ts-jest in typescript and I am trying to mock a class but I am getting a TypeError. "storage_1.default is not a constructor".

Here is how I am mocking the class.

index.test.ts

import GetAdaptiveCard from '../../GetAdaptiveCard/index'

const mockGetAdaptiveCard = jest.fn();
jest.mock('../../utils/storage', () => {
    return jest.fn().mockImplementation(() => {
        return {
            getAdaptiveCard: mockGetAdaptiveCard
        }   
    })
})
test('http trigger should return adaptive card', async () => {
....
    await GetAdaptiveCard(context, req);//calls AdaptiveCardStorage. The class I am mocking in "../../utils/storage"
...
});

index.ts

import AdaptiveCardsStorage from '../utils/storage';
...
const storage: AdaptiveCardsStorage = new AdaptiveCardsStorage(); //This is where I get the TypeError
const adaptiveCard: string = await storage.getAdaptiveCard(userID, cardName);

utils/storage.ts

export default class AdaptiveCardsStorage {
    /**
     * 
     * Class to interface with adaptive cards storage.
     * 
     */

    private tableService: storage.TableService;
    private tableName: string = Config["TABLE_STORAGE_TABLE_NAME"];

    public constructor() {
        this.tableService = storage.createTableService();
    }

    public async getAdaptiveCard(userID: string, cardName: string): Promise<string> {
        return new Promise((resolve, reject) => {
            this.tableService.retrieveEntity<any>(this.tableName, userID, cardName, (err, result) => {
                if (!err) {
                    resolve(result.Content["_"]);
                } else {
                    reject(err);
                }
            });
        });
    }

}

This is what I got.

    TypeError: storage_1.default is not a constructor


const handleRequest = async function (userID: string, cardName: string, context: Context) {
const storage: AdaptiveCardsStorage = new AdaptiveCardsStorage();
         |                                           ^
const adaptiveCard: string = await storage.getAdaptiveCard(userID, cardName);

at GetAdaptiveCard/index.ts:19:
at dist/GetAdaptiveCard/index.js:7:71
at Object.<anonymous>.__awaiter (dist/GetAdaptiveCard/index.js:3:12)
at handleRequest (dist/GetAdaptiveCard/index.js:29:
at Object.<anonymous> (GetAdaptiveCard/index.ts:9:29)
at dist/GetAdaptiveCard/index.js:7:71

Solution

  • Because you are using ES2015 imports for your code it expects the default export of your module to be available, but in the mock you do not provide one. Fix is very simple:

    jest.mock('../../utils/storage', () => {
        return { // need to add this nested `default` property
            default: jest.fn().mockImplementation(() => {
                return {
                    getAdaptiveCard: mockGetAdaptiveCard
                }   
            })
        }
    })