如何在对象的nodeunit deepEqual测试中跳过epoch字段?

时间:2014-07-10 15:07:09

标签: javascript nodeunit

我正在使用nodeunit对某些Javascript对象运行测试。在某些时候,我有一个类似的验证:

test.deepEqual(originalObject, testObject, 'Sentiment validation');

我验证的对象看起来大致如下:

var originalObject = {
  "sentiments": [
    {
      "sentiment": "negative",
      "user": {
        "_id": null,
        "type": "machine"
      },
      "timestamp": 1404775102
    }
  ]
};

var testObject = {
  "sentiments": [
    {
      "sentiment": "negative",
      "user": {
        "_id": null,
        "type": "machine"
      },
      "timestamp": 1405004493
    }
  ]
};

我的测试总是失败,因为动态创建的对象中的timestamp字段(在这种情况下为testObject)总是不同的;有没有办法告诉deepEqual方法跳过那个单一字段?

2 个答案:

答案 0 :(得分:1)

你可以试试这个。

我没有在原始的两个对象上调用断言,但是我调用了一个修改原始对象并在修改后的两个对象上断言的函数。

将删除时间戳的功能

var getObjectWithoutTimestamp = function(obj){
   var result = {};
   //map is because if there are more than one sentiment in array.
   result["sentiments"] = obj.sentiments.map(function(sentiment){
       var sntmnt = {};
       var user = {"_id":sentiment.user._id,"type":sentiment.user.type};
       sntmnt["sentiment"] = sentiment.sentiment;
       sntmnt["user"] = user;
       return sntmnt;
   });
   return result;
};

将修改原始对象并调用断言的函数。

var assertObjects = function (expected,actual) {
    //// get object excluding timestamp
    var expectedModified = getObjectWithoutTimestamp(expected); 
    var actualModified = getObjectWithoutTimestamp(actual);
    // assert on these two objects. I tried with nodejs assert.
    require('assert').deepEqual(expectedModified,actualModified);
}

调用原始对象上的assertObject函数。

assertObjects(testObject,originalObject);

可能有更好的方法来做到这一点。所以任何改进/帮助都将受到赞赏。

答案 1 :(得分:0)

我知道这是一个古老的问题,但是我时不时地在Google周围寻找是否有好的解决方案,因此我再次遇到了这个问题。然后我有了一个灯泡时刻,以为我会在这里留下一些笔记。

我从不喜欢我为此提出的各种选择。

一种选择是简单地删除您不想测试的字段,这就是@Mritunjay在回答中所做的事情。这很尴尬,而且,它通常会受到ESLint的反对。

另一种选择是预先计算时间戳(或需要忽略的任何字段),以便我们知道要测试的内容。这不仅增加了测试的复杂性,而且通常还增加了基础代码的复杂性。

另一个选择-也许是最大的变化-是使用断言库,例如Chai或Jest's,它们具有忽略字段或提供正则表达式或仅检查类型的功能。对我来说,问题是我更喜欢使用Node的断言库进行测试-少了一点。 ;)

但是我刚刚意识到,一个不会对ESLint造成干扰的简单解决方案是,而不是删除源对象中的值,我们设置使用测试对象中的值-我们正在测试的对象上的数据。

在您的示例中为:

import { strict as assert } from 'assert'

const originalObject = {
  sentiments: [{
    sentiment: 'negative',
    user: {
      _id: null,
      type: 'machine'
    },
    timestamp: 1404775102
  }]
}

const testObject = {
  sentiments: [{
    sentiment: 'negative',
    user: {
      _id: null,
      type: 'machine'
    },
    timestamp: originalObject.sentiments[0].timestamp
  }]
}

assert.deepEqual(originalObject, testObject, 'Sentiment validation')

如果您想使其具有真正的弹性,则可以分别测试timestamp字段。