我想为使用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);
});
});
答案 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对象中的时间。