Jasmine test for object properties

61,501

Solution 1

It's built in now!

describe("jasmine.objectContaining", function() {
  var foo;

  beforeEach(function() {
    foo = {
      a: 1,
      b: 2,
      bar: "baz"
    };
  });

  it("matches objects with the expect key/value pairs", function() {
    expect(foo).toEqual(jasmine.objectContaining({
      bar: "baz"
    }));
    expect(foo).not.toEqual(jasmine.objectContaining({
      c: 37
    }));
  });
});

Alternatively, you could use external checks like _.has (which wraps myObject.hasOwnProperty(prop)):

var _ = require('underscore');
describe('my object', function() {
  it('has these properties', function() {
    var props = [
      'property1',
      'property2',
      ...
    ];
    props.forEach(function(prop){
      expect(_.has(myObject, prop)).toBeTruthy();
    })
  });
});

Solution 2

The simplest solution? Sort.

var actual = Object.keys(myObject).sort();
var expected = [
  'property1',
  'property2',
  ...
].sort();

expect(actual).toEqual(expected);

Solution 3

it('should contain object keys', () => {
  expect(Object.keys(myObject)).toContain('property1');
  expect(Object.keys(myObject)).toContain('property2');
  expect(Object.keys(myObject)).toContain('...');
});

Solution 4

I ended up here because I was looking for a way to check that an object had a particular subset of properties. I started with _.has or Object.hasOwnProperties but the output of Expected false to be truthy when it failed wasn't very useful.

Using underscore's intersection gave me a better expected/actual output

  var actualProps = Object.keys(myObj); // ["foo", "baz"]
  var expectedProps =["foo","bar"];
  expect(_.intersection(actualProps, expectedProps)).toEqual(expectedProps);

In which case a failure might look more like Expected [ 'foo' ] to equal [ 'foo', 'bar' ]

Share:
61,501
sfletche
Author by

sfletche

Updated on August 23, 2022

Comments

  • sfletche
    sfletche almost 2 years

    What I'd like to do

    describe('my object', function() {
      it('has these properties', function() {
        expect(Object.keys(myObject)).toEqual([
          'property1',
          'property2',
          ...
        ]);
      });
    });
    

    but of course Object.keys returns an array, which by definition is ordered...I'd prefer to have this test pass regardless of property ordering (which makes sense to me since there is no spec for object key ordering anyway...(at least up to ES5)).

    How can I verify my object has all the properties it is supposed to have, while also making sure it isn't missing any properties, without having to worry about listing those properties in the right order?

  • Martin Schneider
    Martin Schneider over 7 years
    but by the second way the values can't be ignored, right?!
  • Plato
    Plato over 7 years
    good point, OP needs first approach for use case of "test keys present without testing values"
  • Daniel Bidulock
    Daniel Bidulock over 6 years
    Thumbs up to the jasmine.objectContaining part
  • quinz
    quinz over 5 years
    Welcome to StackOverflow! Code-only answers are not considered to be good quality. Please elaborate what your code does and how it helps to resolve the issue.
  • Tiago Martins Peres
    Tiago Martins Peres over 5 years
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.
  • BizzyBob
    BizzyBob about 5 years
    I'm not seeing the toHaveProperty() method. Is this for jasmine?
  • Jhonatan
    Jhonatan about 3 years
    That method is not available for Jasmine
  • bicarlsen
    bicarlsen over 2 years
    The link for jasmine.objectContaining in the answer is broken. Here is the new page.
  • Plato
    Plato over 2 years
    @bicarlsen Thank you, updated. Feel free to use the flagging functionality for edit requests like this in case the OP doesn't log in for a while