Imitating the inclusion of an import that introduces two aliases

Currently, I am in the process of creating unit tests using Jest to simulate various parts of the code that rely on the moment.js library. Just to provide some context, this is a Node+Express project developed in TypeScript with a supporting moment.d.ts file.

The specific import and code block under scrutiny are:

import moment from 'moment';

const durationSinceLastEmail = moment.duration(moment(new Date())
                .diff(moment(user.passwordRecoveryTokenRequestDate)));

The type information provided for the imported moment reference displays two actual items:

(alias) function moment(inp?: moment.MomentInput, format?: moment.MomentFormatSpecification, strict?: boolean): moment.Moment (+1 overload)
(alias) namespace moment
import moment

My implementation uses both forms: moment.duration for the namespace and moment(...params) for the function.

In general, my Jest mocking approach has not been very successful so far. For example:

jest.mock('moment', () => {
    return jest.fn().mockImplementation( () => {
        return {
            duration: (...params) => mockDuration(...params)
        };
    });
});

I have managed to mock the duration function by directly substituting the duration method in a more forceful manner.

const originalDuration: Function = moment.duration;

mockDuration.mockImplementation((...params) => {
    const original = originalDuration(...params);
    // Apply mocks on returning object here
    // or supply entirely new mock object
    return original;
});

moment.duration = mockDuration;

To be honest, the code is quite messy, but it does help me reach halfway as it enables me to track calls to moment.duration(...params). However, all the methods attempted to mock the moment(...) call have either failed or clashed with the above approach (and also failed).

The root of my issues seems to stem from the naming conflict. Therefore, my question would be:

1) Is there any way to separate these different references so they can be handled independently?

or

2) Is there an efficient approach for me to separately mock them or alternatively provide mocking for both the function and the namespace within a single mock object?

Answer №1

To customize the behavior of the `moment` library in your tests, you can create a manual mock by following these steps.

Start by creating a file named `__mocks__/moment.js` at the root of your project alongside the `node_modules` directory:

const momentMock = jest.fn();  // Create the moment mock
momentMock.mockImplementation(() => ({ diff: jest.fn() }));  // Define a custom implementation for the mock

momentMock.duration = jest.fn();  // Add a mock for moment.duration

export default momentMock;  // Export the mock for usage in your tests

In your test files, include the line jest.mock('moment'); to apply the mock:

import moment from 'moment';

jest.mock('moment');  // Implement the moment mock

test('durationSinceLastEmail', () => {
  const user = {
    passwordRecoveryTokenRequestDate: new Date('2019-01-01')
  }
  const durationSinceLastEmail = moment.duration(moment(new Date())
    .diff(moment(user.passwordRecoveryTokenRequestDate)));

  expect(moment).toHaveBeenCalledTimes(2);  // Assertion successful
  expect(moment.duration).toHaveBeenCalledTimes(1);  // Assertion successful
});

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

AngularJS: Utilizing services to make API requests and retrieve JSON data

I am struggling to pass a value from an input field on the view using a service. The service is supposed to call my WebAPI2 and then receive a valid JSON as a response. Unfortunately, I keep getting a promise object that I cannot resolve (even with ".then ...

How can we restrict the type without altering the original type?

import { CSSProperties } from 'react'; type StyleRulesType = Partial<CSSProperties> type StylesDefinition = { [key: string]: StyleRulesType }; const styles: StylesDefinition = { list: { position: 'relative', }, ...

Perfroming unit testing on base class using Jasmine and Angular framework

I have a common base class that I include in every grid component. Currently, I have the specifications for the grid component, but I want to create separate specifications for the base class in its own spec file. The goal is to eliminate redundant code ...

Tips for inserting an HTML element within an exported constant

I need help formatting an email hyperlink within a big block of text. Here is the code snippet: const myEmail = '<a href="mailto:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2e4b564f435e424b6e4b564f435e424b004d41 ...

Debugging Vue with Jest

I am currently troubleshooting my Vue project in VS Code, which uses Jest for testing. Jest Configuration: module.exports = { moduleFileExtensions: [ 'js', 'jsx', 'json', 'vue' ], transform: { ...

What is the process for incorporating a personalized inputComponent JSX <input /> into a react-phone-number-input PhoneInput component?

Instructions to follow when working with code. react-phone-number-input provides the option for users to replace its default <input /> JSX tag with a custom one, requiring the type React.ForwardRefExoticComponent<React.InputHTMLAttributes<HTML ...

Tips for defining types for a function that serves as an argument and can accept any parameters and return any values

I am interested in implementing a debounce function using TypeScript. Below is the code snippet I have written: function debounce(fn: Function, time: number): Function { // ... } However, my eslint is flagging an issue with using Function as a type. Her ...

Encountering a type error in Typescript when assigning a transition component to a Material UI Snackbar

Attempting to implement snackbar alert messages using Material UI in a React JS application with TypeScript. Encountering a type error when trying to modify the transition direction of the snackbar. Referenced the snackbar demo from Material UI documentat ...

Tips for implementing index values in typescript within an Angular Material Table

<mat-cell *matCellDef="let element; let i index">{{ element.patientName }}<input type="hidden" [(ngModel)]="index" value={{i}}/></mat-cell> I created an index variable to access the value in the typescript f ...

Check if a form field's value is lower than another in Angular reactive forms

In the form, I have a field called LDC along with two other fields named limit1 and limit2. My goal is to display an error message if either limit1 or limit2 exceeds the value of LDC, or if the sum of limit1 and limit2 surpasses LDC. I attempted to creat ...

Is it possible to swap out the Firestore module `doc` with the `document` module

I enjoy using the Firebase version 9 modules, however, I find that doc is not to my liking. It would be better if it were document, similar to how collection is not shortened to col. The following code does not function as expected: import { doc, collecti ...

Pattern matching to eliminate line breaks and tabs

Hey there, I'm working with a string: "BALCONI \n\n\t\t\t\t10-pack MixMax chocolade cakejes" and trying to tidy it up by removing unnecessary tabs and new lines. I attempted using .replace(/(\n\t)/g, '&apo ...

What type of code is typically found within a class that has been declared under the ngModule decorator?

As a beginner in the world of Angular, I have noticed various examples that utilize ngModule decorators above an empty class. My question is: Is the class placed right after the ngModule decorator solely for initializing a module, or does it have addition ...

What is the process of asynchronously importing a module's exported function using dynamic imports and then executing it?

When working with asynchronous callbacks in a promise promise.then(async callbackResultValue => { //here }) I experimented with this code: const browserd = await import('browser-detect'); if (typeof browserd === 'function') { ...

Jest: Mocking Redux-thunk API responses – a step-by-step guide

I'm struggling to mock the API response in my thunk. The mock is returning undefined data. Error: expect(jest.fn()).toHaveBeenCalledWith(...expected) Expected: {"payload": {"data": ["hey", "foo"], "resultValue": 0}, "type": "products/setProducts"} ...

Opening a Bootstrap tab programmatically in Angular

I had a previous experience where I had to programmatically open a modal. Take a look at this snippet of code that represents the modal: <div class="modal fade" id="messageModal" tabindex="-1" role="dialog">< ...

Using TypeScript arrow functions to define parameters

When setting "noImplicitAny": true in TypeScript, you may encounter the following errors: Parameter 'x' implicitly has an 'any' type This error can occur with the code snippet: .do(x => console.log(x)); Another error you might s ...

The implementation of the '@' import for Jest testing is crucial for enhancing the efficiency of test cases

Having an issue running tests for my React application that utilizes @ import like this import { something } from "@atoms"; I have successfully mapped it in the tsconfig.json file, and it works fine when I run the application (command: "web ...

The custom validator in Material2 Datepicker successfully returns a date object instead of a string

Im currently working on developing a unique custom validator for the datepicker feature within a reactive form group. Within my code file, specifically the .ts file: form: FormGroup; constructor( private fb: FormBuilder, ...

Managing a click event with an element in React using TypeScript

Hey there, I'm pretty new to TypeScript and React. I have this event where I need to identify the element that triggered it so I can move another element close to it on the page. However, I'm facing some challenges trying to make it work in React ...