reduxjs/redux-toolkit

Expect fetch to have been called with url in test

bigmasonwang opened this issue · 2 comments

When using fetch API, in the test I can simply write

expect(fetch).toHaveBeenCalledWith(
  "https://pokeapi.co/api/v2/pokemon/bulbasaur",
);

But after migrate to rtk-query, I got the error:

AssertionError: expected "spy" to be called with arguments: [ Array(1) ]

Received: 

  1st spy call:

  Array [
-   "https://pokeapi.co/api/v2/pokemon/bulbasaur",
+   Request {
+     "agent": undefined,
+     "compress": true,
+     "counter": 0,
+     "follow": 20,
+     "size": 0,
+     "timeout": 0,
+     Symbol(Body internals): Object {
+       "body": null,
+       "disturbed": false,
+       "error": null,
+     },
+     Symbol(Request internals): Object {
+       "headers": Headers {
+         Symbol(map): Object {},
+       },
+       "method": "GET",
+       "parsedURL": Url {
+         "auth": null,
+         "hash": null,
+         "host": "pokeapi.co",
+         "hostname": "pokeapi.co",
+         "href": "https://pokeapi.co/api/v2/pokemon/bulbasaur",
+         "path": "/api/v2/pokemon/bulbasaur",
+         "pathname": "/api/v2/pokemon/bulbasaur",
+         "port": null,
+         "protocol": "https:",
+         "query": null,
+         "search": null,
+         "slashes": true,
+       },
+       "redirect": "follow",
+       "signal": AbortSignal {},
+     },
+   },
  ]


Number of calls: 1

Why this happened? Here is the sandbox link

fetch has two different signatures:

fetch(url, options)

and

fetch(requestObject)

fetchBaseQuery uses the second one.

I'd recommend that you use something like msw to intercept outgoing requests, but you probably can also mock, but then you'd have to inspect the Request object passed into the mock closer.

Thanks @phryneas , and this works for me

  // vitest-fetch-mock
  fetch.mockResponseOnce(JSON.stringify({ name: "bulbasaur" }));
  const expectedRequest = new Request(
    "https://pokeapi.co/api/v2/pokemon/bulbasaur",
    { signal: new AbortController().signal },
  );
  expect(fetch).toHaveBeenCalledWith(expectedRequest);