3

I am trying to mock some ES6 named modules with Jest and so far no luck. Here's my directory structure,

root
  - app
      controller.js
      service.js
  - tests
      controller.test.js
  babel.config.json
  jest.config.mjs
  package.json
  yarn.lock
  

Here's how service.js looks like,

export const getCustomers = async () => {
    const result = await new Promise( ( resolve ) => {
        resolve( {
            name: "Json Bourne",
            age: 27,
            profession: "Its a secret"
        } );
    } );
    return result;
}

And controller.js

import { getCustomers } from "./service";

export const getAllCustomers = async () => {
    const result = await getCustomers()
    return { ...result }
}

And the test with the mocks

import { jest } from '@jest/globals'
import { getAllCustomers } from "../app/controller";

jest.mock( '../app/service', () => ( {
    __esModule: true,
    getCustomers: jest.fn().mockReturnValue( {
        name: "Dummy Name",
        age: 27,
        profession: "Dummy Profession"
    } )
} ) );

describe( 'controller tests', () => {
    it( 'should correctly return customers', async () => {
        const mockResult = {
            name: "Dummy Name",
            age: 27,
            profession: "Dummy Profession"
        }
        const result = await getAllCustomers();
        expect( result ).toBeDefined();
        expect( result ).toStrictEqual( mockResult );
    } );
} );

This code does not use the mock function for some reason and hits the real getCustomers. This implementation is based on the accepted answer in this similar question. I tried using the jest.spyOn on like below and that gave me an error TypeError: Cannot assign to read only property 'getCustomers' of object '[object Module]' I am using ES6 Modules. "type": "module", in `package.json.

import * as service from "../app/service";
jest.spyOn( service, "getCustomers" ).mockReturnValue( mockResult );

Any leads on how I can use mocking with ES6 named imports?

PS: I tried using default imports and it worked. i.e. the following code worked

// In service.js
const getCustomers = // Same code like above
const service = {
    getCustomers
}
export default service;

And in test

import service from "../app/service";
jest.spyOn( service, "getCustomers" ).mockReturnValue( mockResult ); // This worked

But I want to use the named imports. I don't want to convert my code to use the default imports. Any help is really appreciated. Thanks in advance.

Klaus
  • 1,641
  • 1
  • 10
  • 22

0 Answers0