Chai's statement states whether an object’s structure contains at least another object’s structure

I use Mocha for unit testing and Chai for statements.

I would like to find an easy-to-use solution to check if the object has the structure and properties defined in my comparison object. But I do not need the objects to be completely equal. The test object must contain at least all the properties in my test object, but it can also contain other properties that are not currently being tested.

So, I want to test the block to see if it returns an object that it returns with at least the name “foo”, which itself is an object that at least contains the “bar” property with a value of 10. So, y I have this expected result for testing against:

var expected = {foo: {bar: 10}}; 

I call my block and get my test object in the sut variable:

 var sut = MyUnit.myFunction(); 

So, for different tiers, I expect these results:

 // Success. Exact match {foo: {bar: 10}} // Fail. Structure is ok, but property value is wrong. {foo: {bar: 11}} // Fail. property bar is missing. {foo: {qux: 20}} // Success. All properties match. Extra properties (baz) in sut are ignored: {baz: 'a', foo: {bar: 10, baz: 20}} 

And then I want to compare it in a convenient way. I could check all the properties individually or split it into several tests, but I was hoping I could do something like

 sut.should.deep.contain.all(expected); 

However, I got the following unexpected result, even if the objects are exactly the same:

AssertionError: expected {foo: {bar: 10}} to have the 'foo' property from {bar: 10} but received {bar: 10}

Of course, I tried this and a couple of other options. The simplest test for equality does not work if the object contains additional properties.

 sut.should.eql(expected); 

AssertionError: expected {foo: {bar: 10, qux: 20}} to a depth of {foo: {bar: 10}}

I tested other combinations of have and contains along with deep , any or all , but no one satisfied my desire.

I found a duplicate question " Chai deep contains a statement on nested objects ", but the only (downvoted) answer does not make sense. It calls deep.eql , which is redundant, and above that it just doesn't work, because it checks for strict equality.

I know that I can test all the properties individually, but it would be nice to have a readable method with one expression to check if one object is a "subset" of another.

Update: I ended up using Shallow Deep Equal for Chai.

+4
source share
2 answers

There are several plugins for Chai that can solve this problem.

chai-subset

There is this subset plugin for Chai that should be able to do this.

I use Mocha in the browser, but although it should be compatible with the browser, I do not have this plugin yet.

In any case, this library contains a general answer to the question, and after its inclusion the following work should work:

 sut.should.containSubset(expected); 

Chai-shallow deep sea equals

chai-subset does not seem to have the version required to run in the browser, so I continued to search for plugins. Another one I found is chai-shallow-deep-equal .

This plugin can also be used in a browser. After he downloaded it from Git and used the description on the plugin, resulting in:

 sut.should.shallowDeepEqual(expected); 

Now it will beautifully ignore additional properties in sut , but it will also give good statements when properties are missing or differ in expected . The following message will appear:

AssertionError: you are expected to have a "2", but get a "20" along the path / foo / qux.

It does not display all statements. If you have two errors in the object, you will get only one (first) statement error. This is not a problem for me, but it can be confusing because it may seem that the fix you made introduced a new problem while it was already there.

Chai-fuzzy

I have not tried chai-fuzzy , ( GitHub ), but it seems that it can solve the same problem, and its repository also contains a browser-compatible plug-in version. However, it also requires another library called Underscore, which seems a little redundant for this purpose. The syntax will look like this:

 sut.should.be.like(expected); 
+8
source

Correct me if I misunderstood, but the following will work with simple chai.

 expect({foo: {bar: 10}}).to.have.deep.property('foo.bar', 10); // Success expect({foo: {bar: 11}}).to.have.deep.property('foo.bar', 10); // Fail expect({foo: {qux: 20}}).to.have.deep.property('foo.bar', 10); // Fail expect({baz: 'a', foo: {bar: 10, baz: 20}}).to.have.deep.property('foo.bar', 10); // Success 
+1
source

Source: https://habr.com/ru/post/984497/


All Articles