This answer is a paraphrase of the accepted answer. It is added only because of this exact suggestion to the accepted answer was rejected.
You can explicitly check whether the object has a property named bar or foo.
delete data.foo;
delete data.bar;
expect(data).not.toHaveProperty('bar');
expect(data).not.toHaveProperty('foo');
For nested properties:
delete data.nested.property;
expect(data.nested).not.toHaveProperty('property');
// or
expect(data).not.toHaveProperty('nested.property');
Or make this less repeating by looping over the properties that will be removed.
const toBeRemoved = ['foo', 'bar', 'nested.property'];
toBeRemoved.forEach((prop) => {
expect(data).not.toHaveProperty(prop);
});
However, the loop approach isn't too great for possible nested objects. What you are looking for is expect.not.objectContaining().
expect({baz: 'some value'}).toEqual(expect.not.objectContaining(
{foo: expect.anything()}
));
This approach works fine but has one unfortunate edge case: It matches when the property exists, but is undefined or null:
expect({foo: undefined}).toEqual(expect.not.objectContaining(
{foo: expect.anything()}
));
would also match. To fix this you can explicitly add those values to be included in the check. You need the jest-extended package for the toBeOneOf() matcher.
expect({foo: undefined}).toEqual(expect.not.objectContaining(
{foo: expect.toBeOneOf([expect.anything(), undefined, null])}
));
An example with nested props that, expectedly, fails:
const reallyAnything = expect.toBeOneOf([expect.anything(), undefined, null]);
expect({foo: undefined, bar: {baz: undefined}}).toEqual(
expect.not.objectContaining(
{
foo: reallyAnything,
bar: {baz: reallyAnything},
}
)
);