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?
jest.mock('@organisation/framework', () => {DatabaseFacade: DatabaseInstance})? Does that work? (Make sure to call it before the import)