25

Chai has an include method. I want to test to see if an object contains another object. For example:

var origin = {
  name: "John",
  otherObj: {
    title: "Example"
  }
}

I want to use Chai to test if this object contains the following (which it does)

var match = {
  otherObj: {
    title: "Example"
  }
}

Doing this does not appear to work:

origin.should.include(match)

5 Answers5

34

Hei, just published chai-subset. Check this out: https://www.npmjs.org/package/chai-subset This should work for you)

 var chai = require('chai');
 var chaiSubset = require('chai-subset');
 chai.use(chaiSubset);

 var obj = {
     a: 'b',
     c: 'd',
     e: {
         foo: 'bar',
         baz: {
             qux: 'quux'
         }
     }
 };

 expect(obj).to.containSubset({
     e: {
         foo: 'bar',
         baz: {
             qux: 'quux'
         }
     }
 });
eagleeye
  • 438
  • 4
  • 11
18

The include and contain assertions can be used as either property based language chains or as methods to assert the inclusion of an object in an array or a substring in a string. When used as language chains, they toggle the contain flag for the keys assertion. [emphasis mine]

So if you're invoking include on an object (not an array or a string), then it only serves to toggle the contain flag for the keys assertion. By the looks of your example, testing for deep equality would make more sense, possibly checking for the key first.

origins.should.include.keys("otherObj");
origins.otherObj.should.deep.equal(match.otherObj);

Actually, now I browse the other examples, you would probably be happiest with this :

origins.should.have.deep.property("otherObj", match.otherObj)
Kelly
  • 40,173
  • 4
  • 42
  • 51
Frances McMullin
  • 5,516
  • 2
  • 18
  • 19
  • 2
    I did read the docs, but sometimes you need a bit more context, you know? Thanks for this answer. –  Feb 28 '13 at 21:06
  • 1
    That's true, I didn't intend to be mean about it. It's just that the docs for chai are actually quite excellent compared to most docs I encounter (they include examples and everything! =P). I'm glad I was able to help – Frances McMullin Feb 28 '13 at 21:15
12

In chai 4.2.0, for example you can use deep include

chaijs doc examples:

// Target array deeply (but not strictly) includes `{a: 1}`
expect([{a: 1}]).to.deep.include({a: 1});
expect([{a: 1}]).to.not.include({a: 1});

// Target object deeply (but not strictly) includes `x: {a: 1}`
expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
expect({x: {a: 1}}).to.not.include({x: {a: 1}});
jc1
  • 591
  • 5
  • 5
6

If you know the level of the subobject you can simply use:

expect(origin.otherObj).to.include(match.otherObj);

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

Sebastien Horin
  • 10,803
  • 4
  • 52
  • 54
-4

In Chai 1.5.0 you will find handy method

includeDeepMembers

http://chaijs.com/releases/

machnicki
  • 491
  • 5
  • 3
  • 3
    I upvoted this but its actually wrong. includeDeepMembers only works on arrays, not objects. – nhjk Oct 08 '16 at 11:37