Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 282
kramer65 Avatar asked Oct 23 '17 14:10

kramer65


Video Answer


2 Answers

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().

like image 159
VincenzoC Avatar answered Oct 10 '22 13:10

VincenzoC


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));
like image 44
myol Avatar answered Oct 10 '22 11:10

myol