Arrays Chai-测试对象数组中的值

Arrays Chai-测试对象数组中的值,arrays,mocha.js,chai,Arrays,Mocha.js,Chai,我正在为REST端点的结果设置测试,该端点返回一个Mongo数据库对象数组 [{_id: 5, title: 'Blah', owner: 'Ted', description: 'something'...}, {_id: 70, title: 'GGG', owner: 'Ted', description: 'something'...}...] 我希望我的测试验证的是,在返回数组中,它包含应该返回的特定标题。我用柴做的事似乎都不管用。类似于res.body.savedResults.

我正在为REST端点的结果设置测试,该端点返回一个Mongo数据库对象数组

[{_id: 5, title: 'Blah', owner: 'Ted', description: 'something'...},
 {_id: 70, title: 'GGG', owner: 'Ted', description: 'something'...}...]
我希望我的测试验证的是,在返回数组中,它包含应该返回的特定标题。我用柴做的事似乎都不管用。类似于
res.body.savedResults.should.include.something.that.equals({title:'Blah'})
的错误是我假设的,因为记录对象除了title之外还包含其他键和值

有没有办法让它做我想做的?我只需要验证标题是否在数组中,而不关心其他数据可能是什么(即id)


谢谢

这是我在考试中通常做的事情:

var result = query_result;

var members = [];
result.forEach(function(e){
    members.push(e.title);
});

expect(members).to.have.members(['expected_title_1','expected_title_2']);
如果知道返回数组的顺序,也可以执行以下操作:

expect(result).to.have.deep.property('[0].title', 'expected_title_1');
expect(result).to.have.deep.property('[1].title', 'expected_title_2');

另一种解决方案是使用一个函数扩展数组对象,以测试数组中是否存在具有与预期值匹配的所需属性的对象,如下所示

/**
 * @return {boolean}
 */
Array.prototype.HasObjectWithPropertyValue = function (key, value) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][key] === value) return true;
    }
    return false;
};
var result = query_result;
// in my case (using superagent request) here goes
// var result = res.body;

result.HasObjectWithPropertyValue('property', someValue).should.equal(true);
如前所述,以下代码现在与和一起工作。我喜欢这种方法的自然可读性

var chai = require('chai'),
    expect = chai.expect;

chai.use(require('chai-like'));
chai.use(require('chai-things')); // Don't swap these two

expect(data).to.be.an('array').that.contains.something.like({title: 'Blah'});

我发现另一种方法更有用。基本上,使用字符串插值并将对象数组映射到字符串文本数组。然后可以根据字符串数组编写期望值

const locations: GeoPoint[] = [
  {
    latitude: 10,
    longitude: 10
  },
  {
    latitude: 9,
    longitude: 9
  },
  {
    latitude: -10,
    longitude: -10
  },
  {
    latitude: -9,
    longitude: -9
  }
];
const stringLocations: string[] = locations.map((val: GeoPoint) => `${val.latitude},${val.longitude}`);

expect(stringLocations).to.contain('-9.5,-9.5');
expect(stringLocations).to.contain('9.5,9.5');

也许现在最好的方法是使用
deep.members
property

这将检查无序的完全相等。(对于
的不完全相等更改
成员
包括

i、 e

expect([{a:1}]).to.have.deep.members([{a:1}]);//通行证
expect([{a:1}])to.have.members([{a:1}]);//失败
这是一篇关于测试数组和对象的文章

免责声明:这不仅是为了测试title属性,而是为了测试整个对象数组+ 干净、功能性强且无依赖性,只需使用映射来筛选要检查的密钥

比如:

const data = [{_id: 5, title: 'Blah', owner: 'Ted', description: 'something'},{_id: 70, title: 'GGG', owner: 'Ted', description: 'something'}];


expect(data.map(e=>({title:e.title}))).to.include({title:"Blah"});
如果只选中一个键,则更短:

expect(data.map(e=>(e.title))).to.include("Blah");

谢谢。由于我不能保证结果顺序,这就解决了我想要测试的问题。我想说的是,虽然您的答案是正确的,但最好使用
.map()
而不是
.forEach()
推送()
结合使用。Map比forEach[1]更快,可读性更强。:)[1]