Chai - 测试 objects 数组中的值
Chai - Testing for values in array of objects
我正在将我的结果测试设置到一个 REST 端点,return我是一个 Mongo 数据库数组 objects。
[{_id: 5, title: 'Blah', owner: 'Ted', description: 'something'...},
{_id: 70, title: 'GGG', owner: 'Ted', description: 'something'...}...]
我想让我的测试验证的是,在 return 数组中,它包含应该 return 的特定标题。我使用 Chai/Chai-Things 所做的一切似乎都不起作用。我假设 res.body.savedResults.should.include.something.that.equals({title: 'Blah'})
错误,因为记录 object 包含除标题之外的其他键和值。
有没有办法让它做我想做的事?我只需要验证标题在数组中,而不关心其他数据可能是什么 (IE _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']);
如果您知道 return 数组的顺序,您也可以这样做:
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;
};
(我把它放在我的主 test.js 文件中,以便所有其他嵌套测试都可以使用该函数)
然后你可以像这样在你的测试中使用它
var result = query_result;
// in my case (using superagent request) here goes
// var result = res.body;
result.HasObjectWithPropertyValue('property', someValue).should.equal(true);
如所述 following code works now with chai-like@0.2.14 and chai-things。我只是喜欢这种方法的自然可读性。
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
属性
这会检查无序的完全相等性。 (对于 includes
的不完全相等更改 members
)
即
expect([ {a:1} ]).to.have.deep.members([ {a:1} ]); // passes
expect([ {a:1} ]).to.have.members([ {a:1} ]); // fails
这是一篇关于测试数组的很棒的文章和objects
https://medium.com/building-ibotta/testing-arrays-and-objects-with-chai-js-4b372310fe6d
免责声明:这不仅是为了测试 title属性,而是为了测试整个 objects
ES6+
简洁、实用且无依赖性,只需使用映射来过滤您要检查的键
类似于:
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");
我喜欢@sebastien-horin 的建议
但是另一种方式with Should
syntax(针对特定的属性):
const data = [
{ _id: 5, title: 'Blah', owner: 'Ted', description: 'something' },
{ _id: 7, title: 'Test', owner: 'Ted', description: 'something' },
];
data.map((e) => e.title).every((title) => title.should.equal('Blah'));
我正在将我的结果测试设置到一个 REST 端点,return我是一个 Mongo 数据库数组 objects。
[{_id: 5, title: 'Blah', owner: 'Ted', description: 'something'...},
{_id: 70, title: 'GGG', owner: 'Ted', description: 'something'...}...]
我想让我的测试验证的是,在 return 数组中,它包含应该 return 的特定标题。我使用 Chai/Chai-Things 所做的一切似乎都不起作用。我假设 res.body.savedResults.should.include.something.that.equals({title: 'Blah'})
错误,因为记录 object 包含除标题之外的其他键和值。
有没有办法让它做我想做的事?我只需要验证标题在数组中,而不关心其他数据可能是什么 (IE _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']);
如果您知道 return 数组的顺序,您也可以这样做:
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;
};
(我把它放在我的主 test.js 文件中,以便所有其他嵌套测试都可以使用该函数)
然后你可以像这样在你的测试中使用它
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
属性
这会检查无序的完全相等性。 (对于 includes
的不完全相等更改 members
)
即
expect([ {a:1} ]).to.have.deep.members([ {a:1} ]); // passes
expect([ {a:1} ]).to.have.members([ {a:1} ]); // fails
这是一篇关于测试数组的很棒的文章和objects https://medium.com/building-ibotta/testing-arrays-and-objects-with-chai-js-4b372310fe6d
免责声明:这不仅是为了测试 title属性,而是为了测试整个 objects
ES6+
简洁、实用且无依赖性,只需使用映射来过滤您要检查的键
类似于:
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");
我喜欢@sebastien-horin 的建议
但是另一种方式with Should
syntax(针对特定的属性):
const data = [
{ _id: 5, title: 'Blah', owner: 'Ted', description: 'something' },
{ _id: 7, title: 'Test', owner: 'Ted', description: 'something' },
];
data.map((e) => e.title).every((title) => title.should.equal('Blah'));