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

Man*_*tha 2 unit-testing jasmine angularjs momentjs

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

例如

app.filter('timeFormat', function () {
    return function (date) {
        return moment(date).format("LT");
    };
});
Run Code Online (Sandbox Code Playgroud)

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

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

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);
    });
});
Run Code Online (Sandbox Code Playgroud)

fra*_*acz 8

有一个共同的规则是说你不应该嘲笑你不拥有的东西.如果你模拟momentjs函数,你可能会在将来遇到问题.

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

但是,如果你的问题是关于不同的东西,这只是一个很小的例子,你可以(但你不应该)使用callFake模拟一下:

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