5

Ok. I've tried to read other questions here but still didn't find a straightforward answer.

How can I assert a partial object match in an array using chai? Something like the following:

var expect = require('chai').expect;
var data = [ { name: 'test', value: 'bananas' } ];
expect(data).to.be.an('array').that.contains.somethig.like({name: 'test'});

Just to clarify, my intention is to get as close to the example provided as possible.

  • to chain after the .be.an('array') and
  • to provide only the partial object as a parameter (unlike chai-subset).

I really thought that expect(data).to.be.an('array').that.deep.contains({name: 'test'}); would work, but it fails on not being a partial match and I'm kinda screwed there.

KyleMit
  • 30,350
  • 66
  • 462
  • 664
kub1x
  • 3,272
  • 37
  • 38

4 Answers4

11

Since chai-like@0.2.14 the following approch will work:

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({name: 'test'});
Mosius
  • 1,602
  • 23
  • 32
kub1x
  • 3,272
  • 37
  • 38
3

ES6+

Clean, functional and without dependencies, simply use a map to filter the key you want to check

something like:

const data = [ { name: 'test', value: 'bananas' } ];
expect(data.map(e=>e.name)).to.include("test");

and if you want to test multiple keys:

expect(data.map(e=>({name:e.name}))).to.include({name:"test"});

https://www.chaijs.com/api/bdd/

Sebastien Horin
  • 10,803
  • 4
  • 52
  • 54
  • Nice and clean. Although it works for single property (`name` in this case) only. For two or more, you'd have to repeat your singleliner for each. `chai-like` compares all properties of the passed object, while ignoring the rest of the input data. – kub1x May 14 '20 at 18:56
2

Not sure why you dismissed chai-subset as this seems to work:

expect(data).to.be.an("array").to.containSubset([{ name: "test" }]);
robertklep
  • 198,204
  • 35
  • 394
  • 381
  • Well, I must admit I simply don't like the `containSubset` naming and the extra brackets. I was hoping to find a solution purely using `chai` without plugins, but I guess that is not the case. I tried to dig a bit into `.contains.something.like({...})` version (using both `chai-things` and `chai-like`), which I love for sounding so natural, and I thing I've found [why](https://github.com/zation/chai-like/pull/12) it [wasn't working](https://stackoverflow.com/q/41726208/336753) at the first place. I know.. two plugins instead of one, but I just like the phrasing and the simpler parameter more. – kub1x Jun 16 '17 at 23:32
0

A solution without third libraries or plugins:

var data = [ { name: 'test', value: 'bananas' } ];
expect(data.map(({name}) => ({name})).to.deep.include({name: 'test'});