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

标签 javascript unit-testing jasmine

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

我的函数如下所示:

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/

相关文章:

javascript - 从 document.getElementById().value 获取空值

javascript - 生日文本字段的日期选择器

Python:模拟文件以进行单元测试

jasmine - 页面对象 - promise 处理 - 错误 "Cannot read property ' 提交'未定义”

javascript - 通过 json 子数组过滤

javascript - Mapbox GL 画线和贝塞尔曲线

c# - 数据库集成测试结构

java - 如何在单元测试中设置固定的 hashCode-Value

javascript - 如何让 promise 在开 Jest 中落空

javascript - webdriverIO - 未处理的 promise 拒绝 : NoSuchSessionError: invalid session id