Guide to mocking the 'git-simple' branchLocal function using jest.mock

Utilizing the simple-git package, I have implemented the following function:

import simpleGit from 'simple-git';

/**
 * The function returns the ticket Id if present in the branch name
 * @returns ticket Id
 */
export const getTicketIdFromBranchName = async (ticketRegex: RegExp) => {
    const git = simpleGit();

    try {
        const localBranches = await git.branchLocal();
        const currentBranch = localBranches.current;
        const currentBranchTicketMatches = currentBranch.match(ticketRegex);

        if (currentBranchTicketMatches) {
            return currentBranchTicketMatches[0];
        }

        return null;
    } catch {
        return null;
    }
};

I am attempting to write a unit test for this function:

import { getTicketIdFromBranchName } from '@/utils/git-info';

const TICKET_ID_REGEX = /((?<!([A-Z]{1,10})-?)[A-Z]+-\d+)/.source;

describe('[utils/git-info]', () => {
    it('getTicketIdFromBranchName | Function should correctly identify ticket Id when one is present', async () => {
        const ticketId = 'CLO-1234';

        jest.mock('simple-git', () => {
            const mGit = {
                branchLocal: jest.fn(() => Promise.resolve({ current: `${ticketId} DUMMY TEST` })),
            };

            return jest.fn(() => mGit);
        });

        const result = await getTicketIdFromBranchName(new RegExp(TICKET_ID_REGEX));

        expect(result === ticketId).toEqual(true);
    });
});

Unfortunately, the unit test fails, indicating that it expected to receive true but instead received false on the final line.

I suspect that my usage of jest.mock may be incorrect.

Answer №1

The official guide provides vital information on the usage of jest.mock.

Important: To ensure proper mocking, it is necessary for jest.mock('moduleName') to be within the same scope as the require/import statement.

While you are calling jest.mock('moduleName') inside the test case function scope, you are importing the git-info module in the module scope. This mismatch is why the mock doesn't function correctly.

To resolve this issue, utilize require('moduleName') or await import('moduleName') within the test case function. The order of the require/import and jest.mock() statements is irrelevant.

git-info.js:

import simpleGit from 'simple-git';

/**
 * This function retrieves the ticket ID, if present, from the branch name
 * @returns ticket ID
 */
export const getTicketIdFromBranchName = async (ticketRegex) => {
  const git = simpleGit();

  try {
    const localBranches = await git.branchLocal();
    const currentBranch = localBranches.current;
    const currentBranchTicketMatches = currentBranch.match(ticketRegex);

    if (currentBranchTicketMatches) {
      return currentBranchTicketMatches[0];
    }

    return null;
  } catch {
    return null;
  }
};

git-info.test.js:

const TICKET_ID_REGEX = /((?<!([A-Z]{1,10})-?)[A-Z]+-\d+)/.source;

describe('[utils/git-info]', () => {
  it('getTicketIdFromBranchName | Function should return correct ticket Id when available', async () => {
    const { getTicketIdFromBranchName } = await import('./git-info');
    const ticketId = 'CLO-1234';

    jest.mock(
      'simple-git',
      () => {
        const mGit = {
          branchLocal: jest.fn(() => Promise.resolve({ current: `${ticketId} DUMMY TEST` })),
        };

        return jest.fn(() => mGit);
      },
      { virtual: true }
    );

    const result = await getTicketIdFromBranchName(new RegExp(TICKET_ID_REGEX));

    expect(result === ticketId).toEqual(true);
  });
});

Test outcome:

 PASS  stackoverflow/71808909/git-info.test.js (7.439 s)
  [utils/git-info]
    ✓ getTicketIdFromBranchName | Function should return correct ticket Id when available (6892 ms)

-------------|---------|----------|---------|---------|-------------------
File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------|---------|----------|---------|---------|-------------------
All files    |   84.62 |       50 |     100 |   81.82 |                   
 git-info.js |   84.62 |       50 |     100 |   81.82 | 19-21             
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        8.215 s, estimated 9 s

package version: "jest": "^26.6.3"

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

Optimal approach for incorporating controller As with UI Router

Currently working on a small search application using AngularJS and Elasticsearch. I am in the process of transitioning the app from using $scope to controller As syntax. I have implemented UI Router for managing routes/states. I have been attempting to us ...

Working with time durations in JavaScript

Is there a way to calculate the duration between a start time and an end time including both hours and minutes? Currently, I have code that only provides me with the hours. Is there any modification I can make to include minutes as well? If so, what chan ...

Navigating the route with quickness

Upon accessing the localhost, I encountered an issue with the code snippet below: When I try to access it, I receive an error message saying "Cannot GET /". var express = require('express'); var router = express.Router(); /* GET home page. */ r ...

Storing basic input values for a function

I am currently working on developing a versatile method that is capable of accepting any number of parameters, while storing the input type for future use. Let's take a look at an example: const customizedFunction = <A extends any[]>(innerFunct ...

Access-Control-Allow-Headers does not allow the use of X-Requested-With

I'm currently working on a system that includes an add item to cart feature. This functionality involves using Jquery's $.ajax method. However, I've encountered an error when attempting to access the online server - "XMLHttpRequest canno ...

Exploring type definition for function arguments in TypeScript and React

There is a high-order component (HOC) designed to store the value of one state for all input and select elements. The output function accepts arguments ({text: Component, select: Component}). An error is displayed while typing an argument: TS2322: Type &ap ...

Performing an ASync call to the GetData routine in MongoClient using NodeJS

Combining code snippets from https://www.w3schools.com/nodejs/nodejs_mongodb_find.asp and https://stackoverflow.com/questions/49982058/how-to-call-an-async-function#:~:text=Putting%20the%20async%20keyword%20before,a%20promise%20to%20be%20resolved. Upon ob ...

react-i18next: issues with translating strings

I encountered a frustrating issue with the react-i18next library. Despite my efforts, I was unable to successfully translate the strings in my application. The relevant code looked like this: App.tsx: import i18n from 'i18next'; import { initR ...

Tips for resolving the React Hook Type Error issue

Error Image const isLoggedIn = true; const handleChangeEvent = () => {}; const [displayPassword, setDisplayPassword] = useState(false); const handleTogglePassword = () => setDisplayPassword((prevDisplayPassword) => !prevDi ...

How to dismiss a jQueryMobile dialog without triggering a page refresh

I've encountered a question similar to this before, but there wasn't any solution provided. The issue I'm facing is that I have a form and when a user clicks on a checkbox, I want to open a popup/dialog for them to enter some data. However, ...

Using routes with optional parameters can inhibit the loading of other routes

In my Node.js app based on Express, I have implemented three different routes. app.get('/', function (req, res) { // }) app.get('/findOne', function (req, res) { // }) app.get('/getFour', function (req, res) { // }) Init ...

Error connecting to Firebase Cloud Functions - connection issue

Whenever I call my cloud function, I see the following message in the logs: Function execution took 5910 ms, finished with status: 'connection error'. It seems to be related to promises and returning or !d.exists, but I haven't been able to ...

Change the name of a file to a name chosen by the user while uploading it to an

I'm a beginner when it comes to node.js and I'm facing an issue that I couldn't find a solution for despite looking into various related topics. My problem involves using Node.js on the server side to upload a file and rename it based on a ...

Error encountered: Unexpected identifier in Reactjs code

I created a new application using create-react-app and encountered an Uncaught SyntaxError: Unexpected identifier for this particular line: import React, { Component } from 'react'; within the file public/scripts/app.js: 'use strict' ...

The callback function `(err: any, data: any) => void` does not share any properties with the type `RequestInit`

Inspired by the tutorial at , I am working on a time-based visualization. I am currently using version "d3": "^5.4.0". Here is the code snippet: d3.json('http://127.0.0.1:5000', function (err, data) { if (err) throw err; // Cre ...

Populate an array of objects with various key-value pairs

In my @change method, I receive the following values: changeAttr(id, key, value) { const selections = []; }, id can be any number, key could be: color, size, sex, etc..., and value could be: red, 8, female, etc. Initially, the values might look like ...

Steps to incorporate this jQuery script

After receiving a solution to my problem, I'm struggling with how to actually put it into practice. $(function(){ $.get('file1.php', function(data){ $('#dropdown1').html( data ); }); // when dropdown1 is chang ...

Transferring AgGrid context in a functional React component

I have been working on a component that utilizes AgGrid to display a table, with the data sourced from a Redux selector. My goal is to include a button within a cell in the table that triggers an action based on the specific row's data. However, I a ...

There are no connection events being triggered - using Mongoose version 4.7.1 with Express

My current struggle involves establishing a connection from my express app to MongoDB via Mongoose. Despite the simplicity of the setup, which is as basic as it gets: var mongoose = require('mongoose'); mongoose.connect('mongodb://localhos ...

Instructions for activating the "Navigate to Declaration" feature in TypeScript for JSON files using i18next

Currently, I am actively engaged in a project that involves the use of i18next with react and typescript. In this project, translation keys are defined within .json files. However, a notable drawback of transitioning to json for the translation files is l ...