2

I am incredibly new to Jest, and well unit tests in general and I am suck on writing up a test for something in particular.

I understand you can mock an external module with something like this..

jest.mock('@organisation/library', () => ({ Database: jest.fn(() => ({})), ...., ...., })) 

And if you wish to use an actual method from that you can do something like

const database = jest.requireActual('@organisation/library')

What I want to be able to do is not mock the entire library, but only one method from that library.

Is that possible?

I might explain the code a little further.

We have a file called StationRepository. This file includes a Database method from our JS framework. This file then calls the database and returns a value.

I am wanting to test that database query.

Here is the test

import { DatabaseModule, Pg } from '@organisation/framework' import { StationRepository } from './StationRepository' import { DatabaseConfig } from '../../spec' const DatabaseInstance = new DatabaseModule() beforeAll(async () => { DatabaseInstance.add('default', new Pg('default', DatabaseConfig)) jest.clearAllMocks() }) afterAll(async () => { const database = DatabaseInstance.get() await database.disconnect() }) describe('find timezone', () => { it('can find a timezone', async () => { const ids = [1, 2] const expected = ['Pacific/Auckland', 'Australia/Adelaide'] const results = [] for (const id of ids) { const timezone: string | null = await StationRepository.findTimezone(id) results.push(timezone) } expect(results).toEqual(expected) }) }) 

And the method in the repository

import { DatabaseFacade as Database } from '@organisation/framework' export class StationRepository { /** * Find Timezone * * Finds the station or system timezone and returns * will return station timezone * if no station timezone will return system timezone * if no system timezone null will be returned * * @param {number} stationId - The station id to search on * @param {string} db - Optional - The Database connection * * @return string | null */ public static findTimezone = async ( stationId: number, db?: string, ): Promise<string | null> => { const query = ` SELECT (CASE WHEN stations.timezone IS NOT NULL THEN stations.timezone WHEN systems.timezone IS NOT NULL THEN systems.timezone END ) AS timezone FROM stations INNER JOIN systems ON systems.id = stations.system_id WHERE stations.id = $1 ` const result = await Database.get(db).queryOne<StationTimezone | null>.( query, [stationId], ) if (!result) { return null } return result.timezone } } 

Everything seems to work, creating the connection from the test and all that. It is failing on the actual query Database.get(). This is loaded in via the framework. If I mock the entire framework everything falls over.

So essentially what I want to do is have the framework run as normal, and only replace the DatabaseFacade area to pull in the DatabaseInstance created on the test page.

Is that possible?

5

1 Answer 1

4
const module = '@organisation/framework' jest.mock(module, () => ({ ...jest.requireActual(module), // You may or may not need this line DatabaseFacade: DatabaseInstance })) 

This will replace exported DatabaseFacade with DatabaseInstance.

(answer from comments, to document this question as resolved)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.