Óscar Palacios
Óscar Palacios

Reputation: 561

How can I skip an epoch field in a nodeunit deepEqual test on an object?

I'm running tests on some Javascript objects with nodeunit. At some point, I have a validation that goes like so:

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

The objects I'm validating look approximately like these:

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

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

My test is always failing because the timestamp field in the dynamically created object (testObject, in this case) is always different; is there a way to tell the deepEqual method to skip that single field?

Upvotes: 3

Views: 1971

Answers (2)

Mark Birbeck
Mark Birbeck

Reputation: 2993

I know this is an old question, but every now and then I Google around to see if there is a good solution, so I've just come across this again. And then I had a lightbulb moment, so thought I'd leave some notes here.

I've never liked the various options I've come up with for this.

One option is to simply remove the field that you don't want to test, which is what @Mritunjay is doing in his answer. It's awkward, and what's more, it usually gets a thumbs down from ESLint.

Another option is to precalculate the timestamp (or whatever field it is that needs ignoring) so that we know what to test against. This adds complexity, not only to the tests but usually also to the underlying code.

Yet another option--and probably the biggest change--is to use an assertion library such as Chai or Jest's, which have features to ignore a field or provide a regex or just check the type. The problem for me is that I much prefer using Node's assertion library for my tests--one less moving part. ;)

But I've just realised that one simple solution that doesn't fall foul of ESLint is instead of deleting the value in the source object, we set the value in the test object--using the data on the object we're testing.

In your example it would be:

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

If you wanted to make it really resilient you could test the timestamp field separately.

Upvotes: 0

Mritunjay
Mritunjay

Reputation: 25882

You can try this.

I didn't called the assertion on original two objects but I called a function which modified original objects and assert on modified two objects.

Function which will remove Timestamp

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

Function which will modify original objects and call the assertion.

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

call the assertObject function on your original objects.

assertObjects(testObject,originalObject);

There could be better ways of doing this. So any improvement/help will be appreciated.

Upvotes: 1

Related Questions