在NodeJS中测试对象相等性 [英] Testing objects equality in NodeJS

查看:300
本文介绍了在NodeJS中测试对象相等性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在为一个程序编写测试。我们想编写一个函数测试来验证程序的输出是否符合某些期望。
返回的对象是一个复杂的JS对象(具有嵌套对象,许多属性等等)。

We are writing tests for a program. We want to write a functionnal test that verifies that the output of the program matches some expectation. The object returned is a complex JS object (with nested objects, many properties... etc).

我们想测试这显然与我们的匹配需要。
到目前为止,我们正在浏览对象和预期结果,检查每个属性以及每个嵌套对象。这非常麻烦,我们想知道是否有任何库可以构建所有测试,仅基于对象。例如这样的东西。

We want to test that this obviously matches what we need. Up until now, we were "browsing" the object and the expected outcome, checking for each property, and each nested object. That is very cumbersome and we were wondering if there was any library that would 'build' all the tests, based just on the object. Something like this for example.

var res = {
  a: {
    alpha: [1,2,3],
    beta: "Hello",
    gamma: "World"
    },
    },
    b: 123,
    c: "It depends"
  }
};
var expectation = {
  a: {
    alpha: [1,2,4],
    beta: "Hello",
    gamma: "World"
    },
    },
    b: 123,
    c: "It depends"
  }
};

assert(res, expectation) // -> Raises an error because res[a][b][2] is different from expectation[a][b][2].

[在这个例子中,我简化了对象的复杂性...]

[In the example, I have simplified the complexity of our object...]

我应该坚持这样一个事实,即我们需要一段足够聪明的代码告诉我们什么是不同的,而不是仅仅告诉我们这2个对象是不同的。我们现在关于深度平等,但我们还没有找到任何实际告诉我们差异的东西。

推荐答案

节点有内置的断言模块用于测试。这有一个名为 deepEqual 的方法,用于深度相等检查。

Node has the built in assert module meant for testing. This has a method called deepEqual for deep equality checking.

函数签名是:

assert.deepEqual(actual, expected, [message])

快速编写的函数,用于测试deepEquality并返回diff:

Quickly written function for testing deepEquality and returning diff:

// Will test own properties only
function deepEqualWithDiff(a, e, names){
  var dif = {};
  var aKeys = Object.keys(a);
  var eKeys = Object.keys(e);

  var cKeys = aKeys;
  var dKeys = eKeys;
  var c = a;
  var d = e;
  var names = {
    c: names ? names['a'] : 'Actual',
    d: names ? names['e'] : 'Expected'
  }

  if(eKeys.length > aKeys.length){
    cKeys = eKeys;
    dKeys = aKeys;
    c = e;
    d = a;
    names = {
      d: names ? names['a'] : 'Actual',
      c: names ? names['e'] : 'Expected'
    }
  }


  for(var i = 0, co = cKeys.length; i < co; i++){
    var key = cKeys[i];
    if(typeof c[key] !== typeof d[key]){
      dif[key] = 'Type mismatch ' + names['c'] + ':' + typeof c[key] + '!==' + names['d'] + typeof d[key];
      continue;
    }
    if(typeof c[key] === 'function'){
      if(c[key].toString() !== d[key].toString()){
        dif[key] = 'Differing functions';
      }
      continue;
    }
    if(typeof c[key] === 'object'){
      if(c[key].length !== undefined){ // array
        var temp = c[key].slice(0);
        temp = temp.filter(function(el){
          return (d[key].indexOf(el) === -1);
        });
        var message = '';
        if(temp.length > 0){
          message += names['c'] + ' excess ' + JSON.stringify(temp);
        }

        temp = d[key].slice(0);
        temp = temp.filter(function(el){
          return (c[key].indexOf(el) === -1);
        });
        if(temp.length > 0){
          message += ' and ' + names['d'] + ' excess ' + JSON.stringify(temp);
        }
        if(message !== ''){
          dif[key] = message;
        }
        continue;
      }
      var diff = deepEqualWithDiff(c[key], d[key], {a:names['c'],e:names['d']});
      if(diff !== true && Object.keys(diff).length > 0){
        dif[key] = diff;
      }
      continue;
    }
    // Simple types left so
    if(c[key] !== d[key]){
      dif[key] = names['c'] + ':' + c[key] + ' !== ' + names['d'] + ':' + d[key]; 
    }
  }
  return Object.keys(dif).length > 0 ? dif : true;
}

这篇关于在NodeJS中测试对象相等性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆