Is there a jasmine matcher to compare objects on subsets of their properties

JavascriptUnit TestingJasmine

Javascript Problem Overview


I have an object that may be extended along my behavior under test, but I want to make sure that the original properties are still there.

var example = {'foo':'bar', 'bar':'baz'}

var result = extendingPipeline(example)
// {'foo':'bar', 'bar':'baz', 'extension': Function}

expect(result).toEqual(example) //fails miserably

I'd like to have a matcher that would pass in this case, along the lines of:

expect(result).toInclude(example)

I know that I can write a custom matcher, but it seems to me that this is such a common problem that a solution should be out there already. Where should I look for it?

Javascript Solutions


Solution 1 - Javascript

Jasmine 2.0

expect(result).toEqual(jasmine.objectContaining(example))

Since this fix: https://github.com/pivotal/jasmine/commit/47884032ad255e8e15144dcd3545c3267795dee0 it even works on nested objects, you just need to wrap each object you want to match partially in jasmine.objectContaining()

Simple example:

it('can match nested partial objects', function ()
{
    var joc = jasmine.objectContaining;
    expect({ 
        a: {x: 1, y: 2}, 
        b: 'hi' 
    }).toEqual(joc({
        a: joc({ x: 1})
    }));
});

Solution 2 - Javascript

I've had the same problem. I just tried this code, it works for me :

expect(Object.keys(myObject)).toContain('myKey');

Solution 3 - Javascript

I don't think it is that common and I don't think you can find one. Just write one:

beforeEach(function () {
    this.addMatchers({
        toInclude: function (expected) {
            var failed;

            for (var i in expected) {
                if (expected.hasOwnProperty(i) && !this.actual.hasOwnProperty(i)) {
                    failed = [i, expected[i]];
                    break;
                }
            }

            if (undefined !== failed) {
                this.message = function() {
                    return 'Failed asserting that array includes element "'
                        + failed[0] + ' => ' + failed[1] + '"';
                };
                return false;
            }

            return true;
        }
    });
});

Solution 4 - Javascript

I thought that I would offer an alternative using modern javascript map and rest operator. We are able to omit properties using destructuring with rest operator. See further description in this article.

var example = {'foo':'bar', 'bar':'baz'}

var { extension, ...rest } = extendingPipeline(example)

expect(rest).toEqual(example)

Solution 5 - Javascript

jasmine.objectContaining() only works for a single layer.

expect(result).toMatchObject(example) checks that the object example that is passed in matches a subset of the properties of result.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioniweinView Question on Stackoverflow
Solution 1 - JavascriptKamil SzotView Answer on Stackoverflow
Solution 2 - JavascriptChicnaView Answer on Stackoverflow
Solution 3 - JavascriptWouter JView Answer on Stackoverflow
Solution 4 - JavascriptBrandon CulleyView Answer on Stackoverflow
Solution 5 - JavascriptJan CharatanView Answer on Stackoverflow