Is it possible to selectively mock certain components of an external module using jest?

I am totally new to using Jest, especially in regards to unit tests, and I am struggling to write a test for a specific scenario.

I know that you can mock an external module like this..

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

If you want to use an actual method from that module, you can do something like

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

What I'm trying to do is mock only one method from the library, not the entire library itself.

Is this possible?

Let me explain the code a bit further.

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

I want 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 be working well, setting up the connection from the test and all. However, it fails on the actual query Database.get(). This is being loaded in from the framework. If I mock the entire framework, everything breaks.

So essentially, what I want to do is have the framework run normally, but only replace the DatabaseFacade section to use the DatabaseInstance created in the test.

Is this possible?

Answer №1

const framework = '@organisation/framework'
jest.mock(framework, () => ({
    ...jest.requireActual(framework), // Consider using this line
    DatabaseFacade: DatabaseInstance
}))

Here, the exported DatabaseFacade will be replaced with DatabaseInstance.

(response from comments section, confirming resolution of the question)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps should I take to create a slider using my image gallery?

I have a unique photo gallery setup that I'm struggling with: As I keep adding photos, the cards in my gallery get smaller and smaller! What I really want is to show only 4 photos at a time and hide the rest, creating a sliding effect. I attempted ad ...

Once I have verified the user's credentials through a POST request, I will proceed to make a GET request

I am in the process of constructing a dashboard that automates logging into an API and updating specific data elements. I have successfully managed to login and authenticate, but I am unsure how to proceed with chaining the GET request after the POST actio ...

Triggering target selection based on the href attribute consistently executing

How can I accurately determine if an anchor tag contains only a "#" in its href attribute? var link = $('#seller-shop').attr('href'); if (link === '#') { alert('I contain #') } else { alert('I do not cont ...

Creating JavaScript classes based on JSON schemas

I have a JSON file containing information and data related to my work, presented in the following format: { "Employees":[ { "id": 1, "fullName": "Test Test" } ], "Infos":[ { "id": 1, ...

If the width of the window is below 768px, do not execute the function

In order to prevent the showCover() function from firing when the window width is less than 768px on page load AND resize, I have made some adjustments to the code below. Even though the window is smaller than 768px, the function will not be triggered. ...

Refreshing the page causes JavaScript to fail loading

Recently, I encountered a puzzling error. Upon visiting this link The carousel fails to load properly near the bottom of the page. However, if you click on the logo or navigate back to the home page, it works fine. Additionally, performing a command + r ...

Creating automatic page additions using Node.js on Heroku?

Can you assist me with a challenge I'm facing? Currently, I am using node.js and heroku to deploy an application and each time I add a new post, I have to manually update my web.js file. This process was manageable when I had fewer pages, but now it&a ...

Transferring data from SocketIO to Vue.js

Is there a way to effectively transfer data results received from socketIO to the Vue instance? Below is my current code implementation: let socket = io(); let users; socket.on('user-connected', (data) => { users = data.count; }); socket ...

I am looking to incorporate a password recovery page into my login process, but I am facing difficulty navigating to it once the code has been modified

I'm looking to include a forgotten password option on my login page, but I'm facing an issue when trying to navigate to it after updating the code. The website is throwing the following error message: [vue-router] uncaught error during rout ...

Differences in weekend start and end days vary across cultures

Looking for a solution to determine the weekend days per culture code in Typescript/Javascript? While most countries have weekends on Sat-Sun, there are exceptions like Mexico (only Sunday) and some middle-eastern countries (Fri-Sat). It would be helpful ...

using javascript to initiate an ajax request

Apologies if my question seems confusing, I am currently in the process of grasping ajax, JavaScript, and jQuery. Here is my query: Below you can find a snippet of my javascript code: if (colorToCheck == gup("Player1")) { document.getElementById(&apo ...

"Encountering an undefined error when making an AngularJS $http post request and receiving a

I am working on retrieving a specific value from the server side by passing a variable from the front-end (AngularJS javascript) to the backend (PHP) using $http. Once the server side (PHP) receives the value from the front-end, it executes an SQL query to ...

Utilizing Angular to Handle Undefined Variables in String Interpolation

Seeking a way to showcase data obtained from an external API on a webpage using Angular's string interpolation. If no data is retrieved or is still pending, the aim is to display 'N/A'. An attempt was made following this method, but encoun ...

Retrieving data from the database using getStaticProps in Next.js

As I was following a tutorial on Next.js, the instructor did something that deviated from what I had learned in school and left me pondering. Here is what he did: interface FaqProps { faq: FaqModel[]; } export default function Faq({ faq }: FaqProps) { ...

Failing to send contact information using JSON in PHP

I attempted to transmit JSON data to PHP for email processing, but encountered an issue where the process veered into the 'else' condition during debugging. Here is the code snippet: HTML <form id="cbp-mc-form" class="cbp-mc-form" method="po ...

Is there a way to transition an element from a fixed layout position to an absolute layout position through animation?

I am looking to create a dynamic animation effect for a button within a form. The goal is for the button to move to the center of the form, while simultaneously undergoing a horizontal flip using a scale transform. During the midpoint of this animation, I ...

Optimizing Static File Caching in Yii

Having a frustrating issue with Yii where my local development environment caches CSS and JS files. Despite making changes to the file, the edits do not reflect in the output and sometimes causes corruption leading to broken functionality. This problem see ...

Ways to manage your javascript variables

Here is the code snippet I am working with: var json = jQuery.parseJSON(data); console.log(json) When I run this code, the output looks like this: Object {sql: "SELECT venta.cliente_tipodoc,count(*) AS cantidad FROM venta venta", results: Array[1], ...

Link a YAML file with interfaces in JavaScript

I'm currently learning JavaScript and need to convert a YAML file to an Interface in JavaScript. Here is an example of the YAML file: - provider_name: SEA-AD consortiumn_name: SEA-AD defaults: thumbnail Donors: - id: "https://portal.brain ...

Show the menu when hovering in reactjs

Currently, in my react project, I am implementing dropdown menus using the reactstrap css framework. Example.Js <Dropdown className="d-inline-block" onMouseOver={this.onMouseEnter} onMouseLeave={this.onMouseLeave} ...