Manoj Shrestha
Manoj Shrestha

Reputation: 4684

Jasmine: How to unit test my date filters that uses moment.js?

I want to write unit tests for my date filters created using moment.js.

E.g.

app.filter('timeFormat', function () {
    return function (date) {
        return moment(date).format("LT");
    };
});

What's the best way to test the above filter?

Does the following test look good? Or do I have to mock the moment functions? If so, how can we achieve that?

describe('Filter: timeFormat', function () {

    'use strict';

    var $filter;

    beforeEach(module('someApp'));

    beforeEach(inject(function (_$filter_) {
        $filter = _$filter_;
    }));

    it('should return time in localized time format', function () {
        var filterTime = $filter('timeFormat');

        var date = new Date();
        var expectedTime = "5:46 AM";

        date.setHours(5);
        date.setMinutes(46);

        expect(filterTime(date)).toEqual(expectedTime);

        expectedTime = "2:34 PM";
        date.setHours(14);
        date.setMinutes(34);

        expect(filterTime(date)).toEqual(expectedTime);

        expectedTime = "12:59 PM";
        date.setHours(12);
        date.setMinutes(59);

        expect(filterTime(date)).toEqual(expectedTime);

        expectedTime = "11:59 PM";
        date.setHours(23);
        date.setMinutes(59);

        expect(filterTime(date)).toEqual(expectedTime);
    });
});

Upvotes: 2

Views: 4970

Answers (2)

Nish
Nish

Reputation: 137

you can try as below:

var expectedTime = '5:46 AM';
var momentTime = moment(expectedTime);
date.setHours(5);
date.setMinutes(46);
expect(filterTime(date)).toEqual(momentTime._i);

where _i is for time in momentTime object.

Upvotes: 0

fracz
fracz

Reputation: 21249

There is a common rule saying that you should not mock what you do not own. If you mock momentjs functions, you can run into issues in the future.

Imagine that in some future release momentjs would change what LT format means (doubtful, but you can see the problem). After upgrade to the new version, your tests would detect this regression if you used momentjs implementation in your unit tests. On the contrary, if you would mock it and record something like return "5:46 AM" if moment is called with "LT", then your tests would be green although production code would not work due to the momentjs upgrade.

However, if your question is about something different and this was only a minimal example, you can (but you should not) mock moment with callFake:

spyOn(window, 'moment').and.callFake(function (date) {
  return {
    format: function (format) { /* your format implementation */ }
  };
});

Upvotes: 9

Related Questions