Simulating require statements using Jest

Addition.js

module.exports = function add(a, b){
    return a + b;
};

CustomThing.js

var addition = require("./addition");

module.exports = class CustomThing {
    performAddition(a, b){
        return addition(a, b);
    }
}

CustomThingTest.js

test('1 + 2 = 3', () => {
    //Arrange
    var CustomThing = require('./CustomThing');
    var customThing = new CustomThing();

    //Act
    var result = customThing.performAddition(1, 2);

    //Assert
    expect(result).toBe(3);
});

test('addition function mocked', () => {
    //Arrange
    jest.mock('./addition', () => {
        return jest.fn(() => 42);
    });

    var CustomThing = require('./CustomThing');
    var customThing = new CustomThing();

    //Act
    var result = customThing.performAddition(1, 2);

    //Assert
    expect(result).toBe(42);
});

How do I handle mocking the 'addition' dependency when writing tests? The error message received is as follows.

addition function mocked

    expect(received).toBe(expected)

    Expected value to be (using ===):
      42
    Received:
      3

An interesting observation is that running each test individually with .only works flawlessly independently.

I have relied on proxyquire in the past for such scenarios but would like to explore alternative solutions if possible.

Answer №1

During the examination, I incorporated

beforeEach(() =>  {
    jest.resetModules();
});

and all the test cases were successfully validated.

Answer №2

Extracted from the Jest Documentation.

beforeEach(() => {
  jest.resetModules();
});

test('moduleName test 1', () => {
  jest.doMock('../moduleName', () => {
    return jest.fn(() => 1);
  });
  const moduleName = require('../moduleName');
  expect(moduleName()).toEqual(1);
});

test('moduleName test 2', () => {
  jest.doMock('../moduleName', () => {
    return jest.fn(() => 2);
  });
  const moduleName = require('../moduleName');
  expect(moduleName()).toEqual(2);
});

Click here for more details on jest.doMock() method.

Answer №3

For some reason, it seems like mocking works on a per test file basis. I can't explain why ¯\_(ツ)_/¯

The method that yielded the best results for me was organizing the tests in this manner:

// addition.test.js
//Arrange
const add = require('./addition');

test('1 + 2 = 3', () => {
    //Act
    const result = add(1, 2);

    //Assert
    expect(result).toBe(3);
});

Additionally:

// Calculator.test.js
//Arrange
const Calculator = require('./Calculator');

// jest.mock statements are hoisted allowing imports to stay at the top
const addMock = jest.fn(() => 42);
jest.mock('./addition', () => addMock);

test('Calculator', () => {
    const calc = new Calculator();

    //Act
    const result = calc.sum(1, 2);

    //Assert
    expect(addMock).toHaveBeenCalledTimes(1);
    expect(result).toBe(42);
});

You even have the flexibility to provide different mock implementations per test using something like:

addMock.mockImplementation(() => NaN);

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

Are there any similar tools to Graphstream in Java that can be used with HTML5 using canvas and JavaScript?

GraphStream is a revolutionary graph library created in Java that offers Java developers a simple way to visually represent dynamic graphs either in memory, on screen, or in files. Check out this demo video. With GraphStream, you can effectively handle th ...

Looping through an array of nested objects using Vue

I have encountered a challenge with accessing specific data within an array that I am iterating over. The array is structured as follows, using Vue.js: companies: [ name: "company1" id: 1 type: "finance" additionalData: "{& ...

Guide for using two Async Pipe functions in Angular 7

Two different functions are in place to check a specific condition, and the requirement is for both of them to be true simultaneously. How can *ngIf be utilized to achieve this? Currently, setting just one of them works, but the aim is to have both. HTML ...

What methods can you use to locate the CSS selector within HTML that meets certain criteria?

Is it possible to parse a given link and find CSS selectors with attributes that partially or completely match a specific keyword? For example, if the keyword is "print," I want to identify all CSS selectors in the link containing "print" in their name, id ...

Can you help identify the issue in this particular ajax code?

Here is the code I wrote to check if a username exists in the database using Ajax. However, I am facing an issue where the input text from the HTML page is not being sent to the checkusername.php file via $_POST['uname'];. I have tried multiple s ...

Initiating a YouTube video with a click on its thumbnail image - a jQuery tutorial

I am currently working on code that successfully displays YouTube videos. However, I would like the video to start playing when the cover image is clicked. How can I achieve this functionality? Thank you for your help! <div id="video" style="display: ...

Tips for managing modal states in functional React components in React Native using React hooks

Utilizing React hooks to manage modal opening and closing, I encountered an issue with my code. The function 'handleAddClick' is supposed to open the modal when used on TouchableOpacity, while the function 'handleClose' should close the ...

Accurate test counting with the help of decorators for providing unit testing data

I implement a unique method of passing data to my Python unit tests using a function decorator and data-provider-functions. My approach is quite similar to the one demonstrated by this individual. Everything functions smoothly except for one minor, yet bot ...

Using an AngularJS directive to dynamically incorporate Bootstrap classes in the HTML elements

Our application is now incorporating reusable code by creating a simple directive to display content efficiently. Directive Code: angular.module("newsStore.moduleDirectives", []) .directive('renderAboutContent', ['aboutService', r ...

What is the best way to reorganize an object's properties?

Looking for a way to rearrange the properties of an existing object? Here's an example: user = { 'a': 0, 'b': 1, 'c': 3, 'd': 4 } In this case, we want to rearrange it to look like this: user = { &a ...

Inject fresh variable values into the serialization process

Within my login form, I have fields for Username and Password. Upon clicking the login button, a Javascript function is triggered to make an ajax request to the login controller. To serialize the form data, I used the code snippet below: var parameters = ...

Arranging an Array by Two Distinct Characteristics

I currently have an array that is grouped and sorted based on the "Program" attribute, which is working well. However, I now need to sort by a different attribute (Deliverable) within each group. Is this possible? If so, how can I achieve it? Below is an ...

Discovering the necessary WebGL browser Add-ons

I have been developing a WebGL application using ThreeJs to showcase 3D models with various effects (shaders). In order to test if the user's browser can run the app, I need to retrieve a list of supported plugins. The Query: My main dilemma is deter ...

What is the reason for not being able to utilize the same ID more than once?

This snippet of code may not be complete, but it effectively addresses the issue at hand. <body onload="init()"> <nav> <h1 style="font-family:Helvetica;"> <ul class="nav"> <li ><a href="#">Me ...

Navigating to a particular value in Vue: A step-by-step guide

In my Vue application, I have a basic table structure: <tbody> <tr v-for="(item, index) in items"> <td> ... </td> </tr> </tbody> The items are dynamically added using the unsh ...

Triggering this function when clicked

I am trying to figure out a way to trigger this code onClick instead of automatically. Can anyone help me with this question? Below is the JavaScript code snippet: $("input[type=radio],button").each(function () { var outputName = $(this).attr("d ...

Combining two request.get functions into a single one

Is there a way to combine these two functions into one? I have two APIs: /page1 and /page2. My goal is to merge the two arrays into one because the GitHub API only displays 100 objects per page. request.get({ url: 'https://api.github.com/users/an ...

Guide on accessing the final value of a text file using JavaScript

My server side script outputs results in a txt file, where the values stored look like this: 1 2 5 7 10 In order to create a real-time progress bar, I need to fetch the last value from the file using an ajax request while updating the txt file with the l ...

Layer added to map by Mapbox encountered an error during the process

I encountered an error that looks like this: https://i.sstatic.net/TI4HO.png When running the following code snippet: map.on('load', function () { map.addLayer({'type': 'scattermapbox', &ap ...

Display a loading dialog for several asynchronous requests being made via AJAX

When making two asynchronous ajax calls, a loading dialog box is displayed for each call using the code below: jQuery('#msg_writter').show(); After a successful request, the loading dialog is hidden with the following code: jQuery('#msg_w ...