cogm
cogm

Reputation: 285

Jest mocking a dependency that's instantiated before the module export

I'm trying to test a file which exports one default function, and also instantiates an object before the exported function that needs to remain as the same instance every time the exported function is called.

Here's a simplified version of the module:

import { HttpClient } from '../client'

const client = new HttpClient()

export default (params) => {
    const url = 'www.'
    // There's a little bit more code here to generate the url based on the params passed in
    return client.get(url)
}

I want to test that the url send to the client.get() function is correct, so here's the test:

import myModule from '../myModule'
import { HttpClient } from '../client'
jest.mock('../client')

const mockHttpClient = { get: jest.fn(() => 'test') }
HttpClient.mockImplementation(() => mockHttpClient)

it('should parse the query param string', () => {
    console.log(myModule({}))
})

When the test runs, the response from myModule({}) is always undefined.

However, if I move the const client = new HttpClient() line down to just inside the exported function, it works correctly and myModule({}) returns test.

I need the HttpClient to only be defined once, and have the same instance used every time the function is called, so it has to be instantiated outside the function. How can I mock that object creation to return my custom value? Thanks.

Upvotes: 1

Views: 871

Answers (1)

seanplwong
seanplwong

Reputation: 1091

This because when you call import {} from '../client' it will immediately invoke new HttpClient(), before you mock the constructor. you could change your mock to

jest.mock('../client', () => ({
  HttpClient: jest.fn(() => ({
    get: jest.fn(() => 'test'),
  }));
}));

but usually anything involve network IO is async, so you might actually need to return a promise like jest.fn(() => Promise.resolve('test')) or jest.fn().mockResolvedValue('test')

Upvotes: 1

Related Questions