gpt4 book ai didi

javascript - 使用 moment.js 进行单元测试

转载 作者:可可西里 更新时间:2023-11-01 02:09:45 26 4
gpt4 key购买 nike

我是编写单元测试的新手。

我的函数如下所示:

getData() {
return this.parameters.map(p => {
return {
name: p.name,
items: p.items.map(item => {

const toTime = item.hasOwnProperty('end') ? moment.utc(item.end._d).unix() : null;
const fromTime = item.hasOwnProperty('start') ? moment.utc(item.start._d).unix() : null;

return {
id: item.id,
fromTime: fromTime,
toTime: toTime,
};
}),
};
});
}

到目前为止,我的 Jasmine 测试如下所示:

describe('getData()', function() {
it('should return json data', function() {
$ctrl.parameters = [{
name: 'test',
items: [{
id: 1,
fromTime: null,
toTime: null
}, {
id: 13,
fromTime: null,
toTime: null

}]
}];

expect($ctrl.getData()).toEqual([{
name: 'test',
items: [{
id: 1,
fromTime: null,
toTime: null
}, {
id: 13,
fromTime: null,
toTime: null
}]
}]);
});
});

此测试正在运行/通过,但如您所见,我没有测试使用 Moment.js 的三元 if/else。基本上三元组所做的是检查项目是否包含名为 start/end 的属性,如果包含,将该值转换为纪元/Unix 时间戳并将其分配给 toTimefromTime

因此,如果项目有一个名为 end 的属性,其值为 'Sat Oct 31 2015 00:00:00 GMT+0000 (GMT)',那么它将被转换为 ' 1446249600' 并分配给 toTime

如何为它编写测试?

最佳答案

最简单的选择是为输入手动构建几个示例日期。例如:

$ctrl.parameters = [{
name: 'test',
items: [{
id: 1,
start: moment.utc('2017-01-01T01:00:00'),
end: moment.utc('2017-01-01T06:00:00')
}, {
id: 13,
start: moment.utc('2017-01-02T08:00:00'),
end: null

}]
}];

(注意在上面的例子中,我把fromTimetoTime分别改成了startend,因为这就是 getData 所期望的输入。)

然后计算出它们的 unix 时间戳。您可以在外部执行此部分 - 例如,我刚刚在 moment.js 网站上打开浏览器开发人员工具 (F12),在控制台中评估以下语句,并获取时间戳值:

moment.utc('2017-01-01T01:00:00').unix()
moment.utc('2017-01-01T06:00:00').unix()
moment.utc('2017-01-02T08:00:00').unix()

最后,回到单元测试,只需验证时间戳是否与预期值匹配:

expect($ctrl.getData()).toEqual([{
name: 'test',
items: [{
id: 1,
fromTime: 1483232400,
toTime: 1483250400
}, {
id: 13,
fromTime: 1483344000,
toTime: null
}]
}]);

或者,如果您不想在单元测试中使用硬编码时间戳,则可以将每个示例日期存储在其自己的变量中(例如,start1end1) ,然后与例如 start1.unix() 进行比较:

// Arrange
const start1 = moment.utc('2017-01-01T01:00:00');
const end1 = moment.utc('2017-01-01T06:00:00');
const start2 = moment.utc('2017-01-02T08:00:00');
$ctrl.parameters = [{
name: 'test',
items: [{
id: 1,
start: start1,
end: end1
}, {
id: 13,
start: start2,
end: null

}]
}];

// Act
const result = $ctrl.getData();

// Assert
expect(result).toEqual([{
name: 'test',
items: [{
id: 1,
fromTime: start1.unix(),
toTime: end1.unix()
}, {
id: 13,
fromTime: start2.unix(),
toTime: null
}]
}]);

这很好,因为单元测试旨在测试您的代码,而不是 moment.js。这取决于你。

另请注意,我使用的是 Arrange-Act-Assert组织测试的模式。同样,这取决于您,但是一旦您的单元测试开始变得复杂,这往往会让事情更容易理解。

无论哪种方式,您都需要更改在 getData 方法中计算 toTimefromTime 的方式,因为编写的代码不会如果您为 startend 传入 null,则工作。特别是,如果您为 start 传入一个 null 值,item.hasOwnProperty('start') 将返回 true,但它会出错因为它试图评估 item.start._d。相反,我建议将这两行更改为以下内容:

const toTime = item.end ? moment.utc(item.end._d).unix() : null;
const fromTime = item.start ? moment.utc(item.start._d).unix() : null;

我还建议不要使用 moment 对象的 _d 属性,因为这是一个内部(私有(private))变量。由于 startend 已经是 moment 对象,您可以改为这样做:

const toTime = item.end ? item.end.unix() : null;
const fromTime = item.start ? item.start.unix() : null;

此处提供了包含上述所有建议更改的完整 jsbin 示例:

https://jsbin.com/xuruwuzive/edit?js,output

请注意,必须进行一些调整才能使其在 AngularJS 的上下文之外运行(使 getData 成为一个独立函数,直接接受其参数,而不是通过 $ctrl)。

关于javascript - 使用 moment.js 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41144348/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com