【问题标题】:Unit test with moment.js使用 moment.js 进行单元测试
【发布时间】:2016-12-14 13:53:35
【问题描述】:

我是编写单元测试的新手,需要一些帮助来测试函数的一部分。

我的函数是这样的……

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

到目前为止,我的测试看起来像这样(茉莉花)

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

希望能解释清楚!我不确定如何为其编写测试,并希望得到任何帮助/建议。

【问题讨论】:

    标签: javascript unit-testing jasmine


    【解决方案1】:

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

    $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),然后进行比较,例如,@987654333 @:

    // 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 的方式,因为如果您将 null 传递给 start 或 @,所编写的代码将不起作用987654340@。特别是,如果您为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 属性,因为这是一个内部(私有)变量。由于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)。

    【讨论】:

    • 谢谢!它的工作。也感谢您的样品!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2011-11-16
    • 2015-05-28
    • 2012-05-23
    • 2010-11-30
    • 2010-12-31
    相关资源
    最近更新 更多