Jasmine:如何对使用moment.js的日期过滤器进行单元测试?

时间:2015-12-07 22:45:25

标签: angularjs unit-testing jasmine momentjs

我想为使用moment.js创建的日期过滤器编写单元测试。

E.g。

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

测试上述过滤器的最佳方法是什么?

以下测试看起来不错吗?或者我必须嘲笑当下的功能?如果是这样,我们怎样才能做到这一点?

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);
    });
});

2 个答案:

答案 0 :(得分:8)

有一个共同的规则是you should not mock what you do not own。如果你模拟了momentjs函数,你可能会在将来遇到问题。

想象一下,在将来的某个版本中,momentjs会改变LT格式的含义(可疑,但你可以看到问题)。升级到新版本后,如果在单元测试中使用了momentjs实现,则测试会检测到此回归。相反,如果您要模拟它并记录类似返回“5:46 AM”的内容,如果用“LT”调用时刻,那么您的测试将是绿色的,尽管生产代码不会起作用瞬间升级。

但是,如果你的问题是关于某些不同的问题,这只是一个很小的例子,你可以(但不应该)用callFake模仿:

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

答案 1 :(得分:0)

你可以尝试如下:

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

其中_i表示在momentTime对象中的时间。