Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mockIf does not accept typing given in documentation. #220

Open
Akolyte01 opened this issue Nov 11, 2021 · 4 comments
Open

mockIf does not accept typing given in documentation. #220

Akolyte01 opened this issue Nov 11, 2021 · 4 comments

Comments

@Akolyte01
Copy link

The example usage given for mockIf is

fetchMock.mockIf(/^https?:\/\/example.com.*$/, req => {
      if (req.url.endsWith("/path1")) {
        return "some response body"
      } else if (req.url.endsWith("/path2")) {
        return {
          body: "another response body",
          headers: {
            "X-Some-Response-Header": "Some header value"
          } 
        }
      } else {
        return {
          status: 404,
          body: "Not Found"
        }
      }
  })

However when this is attempted in a TypeScript project it results in a Type error.

No overload matches this call.
  Overload 1 of 2, '(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock', gave the following error.
    Argument of type '(req: Request) => "some response body" | { body: string; headers: { 'X-Some-Response-Header': string; }; status?: undefined; } | { status: number; body: string; headers?: undefined; }' is not assignable to parameter of type 'MockResponseInitFunction'.
      Type '"some response body" | { body: string; headers: { 'X-Some-Response-Header': string; }; status?: undefined; } | { status: number; body: string; headers?: undefined; }' is not assignable to type 'Promise<string | MockResponseInit>'.
        Type 'string' is not assignable to type 'Promise<string | MockResponseInit>'.
  Overload 2 of 2, '(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock', gave the following error.
    Argument of type '(req: Request) => "some response body" | { body: string; headers: { 'X-Some-Response-Header': string; }; status?: undefined; } | { status: number; body: string; headers?: undefined; }' is not assignable to parameter of type 'string'.

To give a simpler example

fetchMock.mockIf('url', (req) => {
        return 'some response body';
      });

results in

No overload matches this call.
  Overload 1 of 2, '(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock', gave the following error.
    Argument of type '(req: Request) => string' is not assignable to parameter of type 'MockResponseInitFunction'.
      Type 'string' is not assignable to type 'Promise<string | MockResponseInit>'.
  Overload 2 of 2, '(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock', gave the following error.
    Argument of type '(req: Request) => string' is not assignable to parameter of type 'string'.ts(2769)
    ```
@veloware
Copy link

veloware commented Dec 7, 2021

Same problem here, I tried converting the callback to an async function, but now the tests just fail with it telling me to wrap in act

fetchMock.mockIf('url', async (req) => {
   return 'some response body';
});
    Warning: An update to Home inside a test was not wrapped in act(...).
    
    When testing, code that causes React state updates should be wrapped into act(...):
    
    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */

@hak33m16
Copy link

I ran into the same problem. A quick fix for anyone else that needs it, independent of this library:

jest.spyOn(global, 'fetch').mockImplementation(jest.fn(() => {
  return Promise.resolve({
    json: () => Promise.resolve({ key: 'value' })
  } as Response)
}))

And because it's a spyOn, the changes go away when you call jest.restoreAllMocks(). I ended up turning it into something a little more complex for my project where specific endpoints mapped to specific responses. If you need to do the same, just add an input parameter to the initial jest.fn() and return the promise depending on which endpoint you're calling

@nhebling
Copy link

Hi,

sad to see that this issue exists since about 9 months and no fix since then (the proposal by @hak33m16 is nice, however I included this library to not having to do everything manually).
currently experience the same problem like @Akolyte01 . Would be great to hear a solution to that specific problem as the library is not usable for me if this doesn't work. I'm using TypeScript 4.7.2 and jest 28.1.0. tsconfig.target is set to es2015...maybe that helps.
Thanks

@roy-t
Copy link

roy-t commented Jul 27, 2023

I also ran into this, just for reference the following typing does work:

import type { MockResponseInitFunction, UrlOrPredicate } from 'jest-fetch-mock';
import fetchMock from 'jest-fetch-mock';

// ...

const url : UrlOrPredicate = 'http://www.example.com';
const fn : MockResponseInitFunction = async req => {
  return new Promise(resolve => {
    resolve({
        body: '<body>Hello World!</body>',
        status: 200,
      });
  });
};

fetchMock.mockIf(url, fn);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants