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

46,899

Solution 1

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

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

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

Solution 3

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

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.

Solution 5

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)
Share:
46,899
iwein
Author by

iwein

Check out these awesome teams Click here if you need help with AngularJS Click here if you need help with ReactJS Click here if you need a CTO Read more about me on LinkedIn

Updated on July 08, 2022

Comments

  • iwein
    iwein about 2 years

    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?

  • Siva
    Siva over 9 years
    Is there a way to do the same thing for an object containing different values and similar keys?
  • Kamil Szot
    Kamil Szot over 9 years
    @Siva - Maybe you could try to compare results of Object.keys(obj) instead of your objects directly?
  • KnownColor
    KnownColor over 8 years
    This doesn't quite address the question since it will return true if the values do not match.
  • mginius
    mginius over 2 years
    I think this instruction is referred to Jest. Is it right? toMatchObject is not available into Jasmine (at least up to version available now, which is version 3.9.0)