Simulating an ES6 module that returns a factory function for moment.js

Disclaimer: I'm a beginner with Jest so please bear with me.

I'm currently working on testing a Vue2.js filter named DateFilter using Jest. This filter simply formats a date that is passed to it.

DateFilter.js

import Vue from 'vue';
import moment from 'moment';

const dateFormatter = (dateValue, dateFormat) => {
    return moment(dateValue).format(dateFormat);
};

Vue.filter('date', dateFormatter);

export default dateFormatter;

So, there are three potential unit tests to be performed:

  1. The DateFilter module should export a function

  2. The date filter should initialize moment with the dateValue provided

  3. The date filter should call the format method on moment using the dateFormat supplied

DateFilter.test.js

import moment from 'moment';
import DateFilter from './DateFilter';

describe('DateFilter', () => {
    it('should exist', () => {
        expect(DateFilter).toBeDefined();
        expect(typeof DateFilter).toBe('function');
    });

    it('should utilize moment.format with the given dateValue and dateFormat.', () => {
        // At this point, I am unsure about how to spyOn the moment function and the .format function
        const mockDateFormat = `dateFormat-${Math.random()}`;
        const mockDate = `mockDate-${Math.random()}`;
        jest.mock('moment', () => {
            return { format: jest.fn() }
        });
        // expect moment to have been called with mockDate
        // expect moment(mockDate) to have been called with mockDateFormat
    });
});

Answer №1

Testing the functionality of your dateFormatter requires a good mock of momentjs. Here is a simple way to set up the mock:

First, let's set the mock for momentjs:

jest.mock('moment', () => {
    const momentMock = { format: jest.fn() }

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

If you try passing the object directly to jest.fn, you may encounter errors as different mocks will be generated each time moment is called.

While you can create a more elaborate moment mock, it might not be necessary for your simple function.

It's advisable to separate unit tests, even though they could be combined in some cases. Here are two example tests:

it('calls moment with the dateValue passed.', () => {
    const mockDateFormat = `dateFormat-${Math.random()}`;
    const mockDate = `mockDate-${Math.random()}`;

    dateFormatter(mockDate, mockDateFormat);

    expect(moment).toHaveBeenCalledWith(mockDate)
});

it('calls format with the dateFormat passed.', () => {
    const mockDateFormat = `dateFormat-${Math.random()}`;
    const mockDate = `mockDate-${Math.random()}`;

    dateFormatter(mockDate, mockDateFormat);

    expect(moment(mockDate).format).toHaveBeenCalledWith(mockDateFormat)
});

Keep in mind that you should focus on testing whether moment has been called and if format has been called, rather than delving too deep into how the third-party library works.

Hope this provides some useful guidance!

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

Choosing particular contenteditable divisions using jQuery

Consider the following HTML structure for a specific type of blog post editor: <div class="entry"> <div class="title" contenteditable="true"> <h2>Title goes here</h2> </div> <div class="content" contenteditable ...

What is the purpose of employing useMemo in the Material-UI autocomplete documentation?

My focus is on this specific demo in the autocomplete documentation. In the google maps example, there is a throttled function that is returned from a useMemo with an empty array as the second parameter. However, it raises the question of what exactly is ...

Guide on properly documenting custom function types in JSDoc or TypeScript to ensure accurate referencing for VSCode IntelliSense functionality

I am currently working on documenting custom function types within an object and would greatly appreciate any assistance: A Closer Look at the Issue Consider this basic object declaration with several function properties (addCoordinate, addCoordinateOne, ...

Deactivating one div's class upon clicking on another div

Below is the HTML code snippet: <div class="container"> <ul class="navbar"> <li class="nb-link"><a>Home</a></li> <li class="dropdown"> <a>CBSE</a> <ul class="dropdown-menu"&g ...

Guide to creating unit tests for document.URL in Angular 5 specifications

Currently attempting to simulate document.URL = 'dashboard'; however, encountering an issue where it states that I can't assign to url because its readonly property. This problem arose while writing jasmine test cases click here for image de ...

Guide: Exchanging choices using jQuery and Address plugin

I am trying to find a way to exchange the values of two options with each other. I created a simple fiddle that successfully swaps input values, but when I tried it with select options, it didn't work as expected. The approach I'm using is based ...

Displaying HTML content using Typescript

As a newcomer to typescript, I have a question regarding displaying HTML using typescript. Below is the HTML code snippet: <div itemprop="copy-paste-block"> <ul> <li><span style="font-size:11pt;"><span style="font-family ...

Issue with updating Parent value in Vue component when Child value changes

I am working with an Array to fill a Dialog Vue Component. My setup looks like this: basicInfo: [{ firstName: "John" , lastName: "Doe" }], <basicInfoForm v-model="showBasicInfoForm" :basicInfo="newbasicInfo[0]"></basicInfoFo ...

How can I retrieve the path to a specific subnode using Javascript/JSON?

What is the best way to obtain a JSON path that leads to a specific child node within an object? For example: var data = { key1: { children: { key2:'value', key3:'value', key4: { ... } ...

What is the best way to switch between components in vue.js?

I have created a Dashboard.vue component consisting of two child components: DisplayBooks.vue and sortBooksLowtoHigh.vue. Initially, the sortBooksLowToHigh component is hidden while the displayBooks component is visible by default. The requirement is that ...

Displaying a dynamic map with real-time coordinates sourced from a database using a combination of ajax and php

I'm currently facing an issue where my solution to retrieve coordinates for a specific place from a database and display a map centered on them is not working as expected. The problem seems to be arising because the map is being initialized without an ...

VueJS waits until the loop is complete before executing a re-render

Check out this VueJS code snippet: new Vue({ el: '#app', data: { tiles: [ { isActive: false }, { isActive: false }, { isActive: false }, { isActive: false }, { isActive: false } ] }, methods: { ...

What could be causing document.getElementById to return null?

I've been troubleshooting my code and noticed that one of the methods in my JavaScript file is not functioning correctly. Does anyone have any insights into why this might be happening? index.html: <!DOCTYPE html> <html lang="en"> <he ...

The React Context Value keeps coming back as undefined every time

As a beginner working with contexts, I am taking it slow. Recently, I came across logging Providers to test the value and encountered a constant 'undefined' result. To troubleshoot, I tried moving them side by side in the code to see if it makes ...

Unable to modify document value in MongoDB using Node.js

Currently, I am attempting to fetch the value of a field form that is being sent to a subroute and utilize it to update a database collection. My ability to retrieve the form value and manipulate it is working fine; however, I encounter an issue when I sol ...

Something seems off with React tests using jest and enzyme

I am currently working on setting up unit tests for React components using Jest and enzyme. I have noticed a strange behavior in my testing setup. When the component being tested is located within the test file itself, everything functions properly. Howeve ...

Is there a way to identify the moment when a dynamically added element has finished loading?

Edit: I've included Handlebar template loading in my code now. I've been attempting to identify when an element that has been dynamically added (from a handlebars template) finishes loading, but unfortunately, the event doesn't seem to trig ...

Begin your meteor project with a remote MongoDB server on a Windows operating system

Currently tackling a project that requires me to integrate my meteor project with a remote MongoDB server on Windows. I successfully set the environment variable (MONGO_URL="DB LINK") from OSX using terminal commands, but I'm encountering difficulties ...

Tips for showcasing retrieved JSON with jQuery's ajax functionality

Below is the jquery code I am working with: $.ajax({ type: "POST", url: "Ajax/getTableRecord", data:{ i : id, t: 'mylist'}, dataType: 'json', success: function(data){ alert(data); ...

Utilizing express.js to access an HTML document

var express = require("express"); var fs = require('fs'); var sys = require('sys'); var app = express(); app.use(express.logger()); app.get('/', function(req, res){ fs.readFile('/views/index.html'); }); ap ...