最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Jest expect mock to be called with an object not containing a specific field - Stack Overflow

programmeradmin3浏览0评论

I want to verify that a mocked API is called with an object which does not contain a specific field.

expect(api.method).toBeCalledWith(expectedObject);

Since the actual parameters of the api.method call can be a subset of the expectedObject this test also passes if the actualObject contains further fields (among which the specific field might be).

How can I rewrite the test in a way, that the tests fails if the actualObject is not equal to the expectedObject?

I want to verify that a mocked API is called with an object which does not contain a specific field.

expect(api.method).toBeCalledWith(expectedObject);

Since the actual parameters of the api.method call can be a subset of the expectedObject this test also passes if the actualObject contains further fields (among which the specific field might be).

How can I rewrite the test in a way, that the tests fails if the actualObject is not equal to the expectedObject?

Share Improve this question edited Mar 14, 2019 at 15:15 skyboyer 23.7k7 gold badges62 silver badges71 bronze badges asked Mar 14, 2019 at 10:16 yN.yN. 2,2577 gold badges36 silver badges53 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 7

you can try something like this

// get the first call to your method
const method = api.method.mock.calls[0]; 

//check if you have expectedObject as a subset of the arguments
expect(method[0]).toMatchObject(expectedObject); 

//key is the field that shouldn't be part of the arguments
expect(method[0].has(key)).toEqual(false); 
// since several tests use this mock I have to ensure to have the latest call
const lastMockApiCall = api.method.mock.calls[api.method.mock.calls.length - 1]; 
const apiCallParams = lastMockApiCall[0];
expect(apiCallParams).not.toHaveProperty('specificFieldIdontWant');

Even when the previous methods does work, it feels unfortable to access 0 indexes and nested properties and, in the end, doing manual parisons. So I prefer this method:

expect(api.method).toBeCalledWith(
  expect.not.objectContaining({
    notWantedProperty: expect.anything(),
  })
);

Also, this will check for previous calls and not only the indexed call. And looks better on the logs:

    Expected: ObjectNotContaining {"name": Anything}
    Received: ...

Be careful, since it will try to match the whole object and not every property separately. For example, if your api has been called with the following object:

{
  "foo": "foo",
  "bar": "bar"
}

The following expect would NOT fail:

expect(api.method).toBeCalledWith(
  expect.not.objectContaining({
    foo: expect.anything(),
    baz: expect.anything(),
  })
);

Because you didn't call the API with both properties, so I would create a new expect for every property:

expect(api.method).toBeCalledWith(
  expect.not.objectContaining({ foo: expect.anything() })
);
expect(api.method).toBeCalledWith(
  expect.not.objectContaining({ baz: expect.anything() })
);

I'm using the following

expect(body[0].email).toEqual(undefined);

Which is passing when there is no email in the first object of the returned API array.

发布评论

评论列表(0)

  1. 暂无评论