【问题标题】:Matching momentJS objects don't 'equal' in jasmine test茉莉花测试中匹配的momentJS对象不“相等”
【发布时间】:2017-05-13 21:02:43
【问题描述】:

我有一套 Jasmine 测试作为我基于 angular-cli 的项目的一部分。我的断言之一是:

expect(dispatchSpy).toHaveBeenCalledWith({
  type: 'SET_RANGE', payload: { value: 'Weekly', start: moment('2017-04-24'), end: moment() }
});

但是,我收到以下错误。

使用 [ Object({ type: 'SET_RANGE', payload: Object({ value: 'Weekly', start: Mon Apr 24 2017 00:00:00 GMT+0100, end: Sat 2017 年 4 月 29 日 00:00:00 GMT+0100 }) }) ] 但实际调用是 [ Object({ type: 'SET_RANGE', payload: Object({ value: 'Weekly', start: Mon Apr 24 2017 00:00) :00 GMT+0100,结束:2017 年 4 月 29 日星期六 00:00:00 GMT+0100 }) }) ]

显然这些显示相同,但​​我在其他地方遇到过这个问题,momentJS 对象的某些属性不匹配。所以我通常会使用:

expect(moment('2017-01-01').format()).toEqual(moment('2017-01-01').format())

但是我在使用).toHaveBeenCalledWith(时不能使用format()

有什么建议吗?

【问题讨论】:

  • 请展示您正在测试的代码并自行测试,可能有更好的测试方法。 dispatchSpy 是从哪里来的?显然,moment() 甚至不会松散地等于moment() - 它们可以指代不同的时间时刻。一个好方法是存根moment(它应该是可注入的)。

标签: angular typescript jasmine momentjs karma-jasmine


【解决方案1】:

您可以使用jasmine.objectContaining 测试部分对象相等性。正如@Dave Bush 所指出的,您需要手动检查时刻对象。您可以使用jasmine custom matchermoment().isSame 为其创建自定义匹配器。

这是一个使用 Jasmine 2 编写的 JavaScript 示例测试:

describe('Moment containing object', function () {   

    beforeEach(function () {
        jasmine.addMatchers({
            toBeEqualMoment: function () {
                return {
                    compare: function (actual, expected) {
                        let result = {};
                        result.pass = actual.isSame(expected);
                        return result;
                    }
                };
            }
        });
    });

    it('is equal to moment containg object', function () {
        let input = {type: 'SET_RANGE', payload: { value: 'Weekly', start: moment('2017-04-24'), end: moment() }};
        let fooSpy = jasmine.createSpy('foo');

        fooSpy(input);

        let joc = jasmine.objectContaining;
        expect(fooSpy).toHaveBeenCalledWith(joc({type: 'SET_RANGE', payload: joc({value: 'Weekly'})}));
        let spyCallParam = fooSpy.calls.mostRecent().args[0];
        expect(spyCallParam.payload.start).toBeEqualMoment(input.payload.start);
        expect(spyCallParam.payload.end).toBeEqualMoment(input.payload.end);
    });

});

Run on JSFiddle

有关自定义匹配器的更多信息,我推荐@boriscoder 的this article

【讨论】:

    【解决方案2】:

    这里的问题是你在比较两个不同的指针而不是两个不同的值。

    在这种情况下我通常做的是在期望之前创建对象...

    let date = moment('2017-01-01'); expect(date).toEqual(date);

    如果您可以控制最终将与toHaveBeenCalledWith() 一起使用的对象,您可以修改代码以便比较指针。

    否则,您可能必须进入低级别并获取使用 calls.argsFor(index) 传递的参数,然后像往常一样将其与 format() 进行比较。

    【讨论】:

      猜你喜欢
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2014-12-22
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多