Socket
Book a DemoInstallSign in
Socket

vitest-json

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vitest-json

Vitest matcher for working with JSON

1.0.2
latest
Source
npmnpm
Version published
Weekly downloads
3
Maintainers
1
Weekly downloads
 
Created
Source

vitest-json

Based on jest-json by Lucas Duailibe

Vitest matchers to work with JSON strings.

Motivation

Say you have a function fetchData the calls fetch with a JSON body and you want to assert that fetchData is building the JSON string correctly.

function fetchData(userId, fields = []) {
  if (!fields.includes("profilePicture")) {
    fields = fields.concat(["profilePicture"]);
  }

  return fetch("/users", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      params: { id: userId },
      fields,
    }),
  });
}

One option to write the test would be to check the final string:

test("fetchData", () => {
  fetchData("ab394js", ["name", "website"]);

  expect(fetch).toHaveBeenCalledWith("/users", {
    method: "POST",
    headers: expect.anything(),
    body: JSON.stringify({
      params: { id: "ab394js" },
      fields: ["name", "website", "profilePicture"],
    }),
  });
});

Ok, this works, but that has a few problems:

  • you are testing that "profilePicture" will be added to the end of the fields list,
  • you are testing the exact orders the keys of the body JSON are added.

If someone changes the test to insert "profilePicture" in the beginning of the list, or change the JSON to JSON.stringify({ fields, params }), your test will now fail because the JSON string changed, even though it's equivalent to the one in the test. That means we have a flaky test. One way to fix it would be:

global.fetch = vitest.fn();

test("fetchData", () => {
  fetchData("ab394js", ["name", "website"]);

  expect(fetch).toHaveBeenCalledWith("/users", {
    method: "POST",
    headers: expect.anything(),
    body: expect.anything(),
  });

  expect(JSON.parse(fetch.mock.calls[0][1].body)).toEqual({
    params: { id: "ab394js" },
    fields: expect.arrayContaining(["name", "website", "profilePicture"]),
  });
});

That's better, and now we can even use expect.arrayContaining() to make sure we assert that the values are present, but don't care about the order.

But that's a really inconvenient way to get the string we're interested (fetch.mock.calls[0][1].body).

Now compare that test to this:

global.fetch = vitest.fn();

test("fetchData", () => {
  fetchData("ab394js", ["name", "website"]);

  expect(fetch).toHaveBeenCalledWith("/users", {
    method: "POST",
    headers: expect.anything(),
    body: expect.jsonMatching({
      params: { id: "ab394js" },
      fields: expect.arrayContaining(["name", "website", "profilePicture"]),
    }),
  });
});

Now that's a very neat test.

API

expect.jsonMatching

In the example above, you can use the expect.jsonMatching asymmetric matcher:

expect(foo).toHaveBeenCalledWith(
  "url",
  expect.jsonMatching({
    foo: "bar",
    spam: "eggs",
  })
);

You can include other asymmetric matchers inside like:

expect.jsonMatching(
  expect.objectContaining({
    foo: expect.stringMatching("bar")
  })
)

expect().toMatchJSON()

It's just sugar for calling JSON.parse() and then expect().toEqual():

expect(json).toMatchJSON(expected);
// equivalent to:
const tmp = JSON.parse(json);
expect(tmp).toEqual(expected);

License

MIT

Keywords

json

FAQs

Package last updated on 14 Feb 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.