2

我正在使用nodeunit. 在某些时候,我有一个这样的验证:

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方法跳过该单个字段?

4

2 回答 2

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

可能有更好的方法来做到这一点。因此,任何改进/帮助将不胜感激。

于 2014-07-11T03:14:54.530 回答
0

我知道这是一个老问题,但我时不时地谷歌一下,看看是否有一个好的解决方案,所以我又遇到了这个问题。然后我有一个灯泡时刻,所以我想我会在这里留下一些笔记。

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

一种选择是简单地删除您不想测试的字段,这就是@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单独测试该字段。

于 2020-02-25T16:04:37.153 回答