kramer65
kramer65

Reputation: 53943

How to mock moment.utc() for unit tests?

I'm just starting out with Node and I'm now writing some unit tests. For the first couple functions I have that works ok, but I now hit upon a function which includes moment.utc() in it. A simplified version of my function looks like this:

function calculate_x(positions, risk_free_interest){
    let x = 0;
    for (let position of positions) {
        let expiry_in_years = get_expire_in_years(moment.utc());
        if (expiry_in_years > 0){
            let pos_x = tools.get_x(expiry_in_years, risk_free_interest);
            x += pos_x;
        }
    }

    return x;
}

I try to test this using the basic node assert testing lib:

"use strict";
const assert = require('assert');
let positions = [{this: 'is', a: 'very', large: 'object'}]; 
assert.strictEqual(calculate_x(positions, 1.8), 1.5);

Since the times at which this is run (and thus the result) will always be different this will always fail.

In Python I can set mock classes and objects. Is there a way that I can solve this problem in Node without giving the moment.utc() as an argument to the calculate_x() function?

Upvotes: 20

Views: 19154

Answers (3)

myol
myol

Reputation: 9858

If you just want to override the utc function and nothing else is working, try adding this in your test suite

moment.prototype.utc = sinon.stub().callsFake(() => new Date(1970, 1, 1, 0, 0));

or

moment.prototype.utc = jest.fn().mockReturnValue(new Date(1970, 1, 1, 0, 0));

Upvotes: 1

Michael Horojanski
Michael Horojanski

Reputation: 4721

const moment = require('moment'); 
const time = moment().valueOf();
moment.now = jest.fn().mockReturnValue(time);

Upvotes: 1

VincenzoC
VincenzoC

Reputation: 31502

Moment lets you Change Time Source

If you want to change the time that Moment sees, you can specify a method that returns the number of milliseconds since the Unix epoch (January 1, 1970).

The default is:

moment.now = function () {
    return +new Date();
}

This will be used when calling moment(), and the current date used when tokens are omitted from format(). In general, any method that needs the current time uses this under the hood.

So you can redefine moment.now to get the custom output when you code executes moment.utc().

Upvotes: 41

Related Questions