Code Monkey home page Code Monkey logo

fetch-mock-jest's People

Contributors

dependabot[bot] avatar skovhus avatar wheresrhys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fetch-mock-jest's Issues

Implement` toHaveRespondedWith`

toHaveRespondedWith(object | status | string ) (using fetch-mock internals to convert to a response config, then use jest objectMatching)

Doesn't seem to mock global by default

Trying this out and i've found that jest is always resolving fetch-mock to the CJS server entry, and not the browser one, which results in the global fetch not being polyfilled. Is there a config i'm missing?

Let fetchMock.mock() return scoped mock

First of all thanks for your awesome library. It makes life much easier when testing my react components that perform API calls.

While experimenting with asserting one question came up. Would it be possible to let fetchMock.mock() return a new mock that only tracks fetch calls where the given filter and options apply so I can assert like that? :

// arrange
const customerAPIMock = fetchMock.mock('path:/customer/');
const productAPIMock = fetchMock.mock('path:/product/');

// act
// Do something that only hits the customer api
// Do something that POST's to the product api

// assert
expect(customerAPIMock).toHaveFetchedTimes(1);
expect(productAPIMock).not.toHaveFetched();
expect(productAPIMock).toHavePostedWith({body: {name: 'Unicorn Milk', price: '$42.00'}});

As far as I understood this can currently be achieved like that using a name...

// arrange
fetchMock.mock({url: 'path:/customer/', name: 'customerAPI'});
fetchMock.mock({url: 'path:/product/', name: 'productAPI'});

// act
// Do something that only hits the customer api
// Do something that POST's to the product api

// assert
expect(fetchMock).toHaveFetchedTimes(1, {name: 'customerAPI'});
expect(fetchMock).not.toHaveFetched({name: 'productAPI'});
expect(productAPIMock).toHavePostedWith({name: 'productAPI'}, {body: {name: 'Unicorn Milk', price: '$42.00'}});

...but it doesn't feel as natural to me as I need to use strings to reference a certain fetch calls. Also this is error prone and can make my tests fail because of typos in the name or accidentally reusing a name and it is lacking auto-completion.

What do you think about the proposed api and do you think it is hard to implement?

How to use fetch-mock-jest with Typescript?

I am having serious trouble making fetch-mock-jest work within my typescript project. Maybe somebody can point me to what I am doing wrong?

After the imports I have the following:

import type { FetchMockStatic } from 'fetch-mock';
import fetch from 'node-fetch';
import 'fetch-mock-jest';
jest.mock('node-fetch', () => {
    return require('fetch-mock-jest').sandbox();
});
const fetchMock = fetch as unknown as FetchMockStatic;

When running the tests I am getting the following error: "TypeError: require(...).sandbox is not a function". What am I doing wrong?

expect fetchMock.lastCall('filter')).toequal bad comparison?

For some reason if i attempt to do this...

const fetchCall = fetchMock.lastCall('path:/2/account/settings');

    await waitFor(() => {
      expect(fetchCall).toEqual([
        'https://api.whenidev.net/2/account/settings',
        {
          method: 'POST',
          headers: mockHeaders(),
          body: JSON.stringify({
            ...settings,
            clockin: {
              ...settings.clockin,
              work: {
                ...settings.clockin.work,
                enabled: true, // the important bit
              },
            },
            payroll: {
              type: 3, // the other important bit
              is_onboarded: true,
            },
            payroll_date: '2015-08-31T12:00:00.000Z', // another important bit
            attendance_alert_employee: 5,
            attendance_alert_manager: 15,
          }),
        }],
      );
    });

I get

 Expected: ["https://api.whenidev.net/2/account/settings", {"body": "{\"clockin\":{\"window\":15,\"mobile\":{\"enabled\":false,\"strict\":false,\"strictOut\":false,\"radius\":100},\"work\":{\"enabled\":true,\"strict\":false,\"strictOut\":false,\"radius\":100}},\"payroll\":{\"type\":3,\"is_onboarded\":true},\"payroll_date\":\"2015-08-31T12:00:00.000Z\",\"attendance_alert_employee\":5,\"attendance_alert_manager\":15}", "headers": {"W-Date-Format": "iso", "W-Token": undefined, "W-UserId": NaN}, "method": "POST"}]
    Received: serializes to the same string

and it's driving me mad, has anyone else figured a way to do this sanely?

Mock calls number stay at 0

So i made a simple jest test :

import fetchMock from 'fetch-mock-jest';

test('Toto', async () => {
    fetchMock.mock('https://toto.com', 200);

    await fetch('https://toto.com');

    expect(fetchMock).toHaveBeenCalled();
});

This test fails, I've tried without asyn/await too. Did I miss something ?

fetchMock.mock doesn't work as expected.

Hi,

I found that fetchMock.mock is a function instead of an object with keys like calls and results. I have found that fetchMock.fetchHandler.mock is what I expected.

fetchMock.mock looks like this

function(...args) {
  setDebugPhase('setup');
  if (args.length) {
    this.addRoute(args);
  }
    
  return this._mock();
}

I was wondering this is expected.
Thanks for your help.

No fallback response defined for GET to /foo

What am I missing here?

const fetch = require("node-fetch");
jest.mock("node-fetch", () => require("fetch-mock-jest").sandbox());
const fetchMock = require("fetch-mock-jest");

describe("bug", () => {
  it("should work!", async () => {
    fetchMock.get("/foo", { bar: "buz" });

    const response = await fetch("/foo").to((r) => r.json());

    expect(response).toEqual({ bar: "buz" });
  });
});
dsandbox@sse-sandbox-twf31:/sandbox$ yarn test
yarn run v1.22.10
warning package.json: No license field
$ jest
 FAIL  src/bug.test.js
  bug
    ✕ should work! (19 ms)

  ● bug › should work!

    fetch-mock: No fallback response defined for GET to /foo

       7 |     fetchMock.get("/foo", { bar: "buz" });
       8 |
    >  9 |     const response = await fetch("/foo").to((r) => r.json());
         |                            ^
      10 |
      11 |     expect(response).toEqual({ bar: "buz" });
      12 |   });

      at Function.Object.<anonymous>.FetchMock.executeRouter (node_modules/fetch-mock/cjs/lib/fetch-handler.js:230:9)
      at Function.Object.<anonymous>.FetchMock._fetchHandler (node_modules/fetch-mock/cjs/lib/fetch-handler.js:144:34)
      at Function.Object.<anonymous>.FetchMock.fetchHandler (node_modules/fetch-mock/cjs/lib/fetch-handler.js:135:14)
      at Function.jestifiedInstance.fetchHandler (node_modules/fetch-mock-jest/jestify.js:27:18)
      at fetch (node_modules/fetch-mock/cjs/lib/index.js:52:51)
      at Object.<anonymous> (src/bug.test.js:9:28)

  console.warn
    Unmatched GET to /foo

       7 |     fetchMock.get("/foo", { bar: "buz" });
       8 |
    >  9 |     const response = await fetch("/foo").to((r) => r.json());
         |                            ^
      10 |
      11 |     expect(response).toEqual({ bar: "buz" });
      12 |   });

      at Function.Object.<anonymous>.FetchMock.executeRouter (node_modules/fetch-mock/cjs/lib/fetch-handler.js:221:11)
      at Function.Object.<anonymous>.FetchMock._fetchHandler (node_modules/fetch-mock/cjs/lib/fetch-handler.js:144:34)
      at Function.Object.<anonymous>.FetchMock.fetchHandler (node_modules/fetch-mock/cjs/lib/fetch-handler.js:135:14)
      at Function.jestifiedInstance.fetchHandler (node_modules/fetch-mock-jest/jestify.js:27:18)
      at fetch (node_modules/fetch-mock/cjs/lib/index.js:52:51)
      at Object.<anonymous> (src/bug.test.js:9:28)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.827 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
sandbox@sse-sandbox-twf31:/sandbox$ ^C

https://codesandbox.io/s/bitter-violet-twf31?file=/src/bug.test.js:0-374

Error message when the body of toHaveFetched has a mismatch

I have a spec that looks something like this

      expect(fetchMock).toHaveFetched(`/my/cool/api`, {
        method: 'POST',
        body: { message: 'this is incorrect', rating: 'thumbs_up' },
      });

Where the body is incorrect - so the test correctly fails, but the error message when I ran the tests output this:

fetch should have been called with /my/cool/api

Implying the API was not even called - however, this is not the case, as when I fixed the body to match the actual output, the test started passing immediately

Simplify implementation

Currently fetch-mock and jest are quite convolutedly entwined in this implementation. It could potentially be simplified with the following approach

  1. Retain the requireActual usage (which now lives in fetch-mock anyway)
  2. Document that users shoudl use this pattern:
jest.mock('node-fetch', jest.fn())
const fetch = require('node-fetch');
const fetchMock = require('fetch-mock-jest').sandbox();
fetch.mockImplementation(fetchMock)
  1. fetch-mock-jest still adds extensions to jest, but that check to see if the mockImplementation is a fetch-mock instance, and error if not.

How to ignore FormData?

I have a fetch method in our production code that creates new FormData()
I suspect this is the reason I keep getting Unmatched POST to [url] error.
How do I ignore the body? I've tried matchPartialBody: true in the options, but that does not work.

TypeError: Cannot read property 'bind' of undefined

I'm trying to use fetch-mock-jest on a project I'm working on but as soon as I import it I get the error TypeError: Cannot read property 'bind' of undefined with the following stacktrace:

at jestify (node_modules/fetch-mock-jest/jestify.js:22:62)
at jestify (node_modules/fetch-mock-jest/jestify.js:114:33)
at Object.<anonymous> (node_modules/fetch-mock-jest/browser.js:4:18)
at config/jest.setup.ts:5:36
at Object.<anonymous> (config/jest.setup.ts:1:1)

Anyone that could help with this problem?

`fetchMock.mock.calls` never updates (possibly jest 26)

After upgrading our codebase to jest 26 and this library to 1.5.1, our tests that used the .toHaveBeenCalled assertions stopped working. It appears that the .mock property is never updated with the calls to the spy.

I tried digging into the code a bit, and it seems like this wrapper does the Object.assign(jestifiedInstance.mock, spy.mock) only once, so those aren't kept in sync. Unfortunately fetchMock.mock is also a method, so we can't just assign jestifiedInstance.mock = spy.mock.

I tinkered around with the code locally and got something working by handling the fetchHandler and mock inside the proxy. It seems to run on our codebase without issue. I'd be happy to spin up a PR if you're interested!

TypeError: Cannot read property 'post' of undefined

I'm trying to spin up a React project with fetch-mock-jest, and having some strange issues! Specifically I'm seeing that the imported object is undefined!

Versions:

├─┬ [email protected]
│ └── [email protected]
├── [email protected] 
└── [email protected] 

Basically all the errors are:

    TypeError: Cannot read property 'post' of undefined

      29 |
      30 |   test('with failed response', async () => {
    > 31 |     fetchMock.post('https://kitsu.io/api/oauth/token', {
         |               ^
      32 |       status: 401,
      33 |       body: {
      34 |         error: 'invalid_grant',

      at Object.<anonymous> (src/actions/loginWithAssertion.test.ts:31:15)

And an excerpt of the code is:

import fetchMock from 'fetch-mock';
afterEach(() => fetchMock.reset());
jest.mock('app/constants/config');

import { LoginFailed, NetworkError } from 'app/errors';

import loginWithAssertion from './loginWithAssertion';
describe('loginWithAssertion', () => {
  test('with successful response', async () => {
    fetchMock.post('https://kitsu.io/api/oauth/token', {
      status: 200,
...

It's not wrong, either, I dropped into a debugger and it's all undefined 🤷‍♀️ I don't have any __mocks__ which could be doing this, it's a brand-new project I'm bootstrapping

For further details:

Keep getting Unmatched GET to "http://example.com"

My code is

import request from 'supertest';
import {app} from '../app';
jest.mock('node-fetch', () => require('fetch-mock-jest').sandbox());
const fetchMock = require('node-fetch');

test('demo created successfully', async () => {
  beforeEach(() => {
    fetchMock.get('*', {
      status: 200
    })

error:

Unmatched GET to https://example.com

1th call to fetch should have had a URL of ... but was undefined

Here is my code:

await new Promise(resolve => setTimeout(resolve, 1000));
console.log("CALLS", fetchMock.mock.calls, fetchMock.mock.calls[1][1].method);
expect(fetchMock).toHaveFetchedTimes(3);
expect(fetchMock).toHaveNthPosted(
  1,
  `${API_HOST}/workouts`,
);

The last assertion is giving me the error "1th call to fetch should have had a URL of http://localhost:1111/workouts but was undefined":

The output from console.log:

CALLS [
[
  'http://localhost:1111/workouts',
  { credentials: 'same-origin', headers: [Object], method: 'GET' }
],
[
  'http://localhost:1111/workouts/',
  {
    credentials: 'same-origin',
    headers: [Object],
    method: 'POST',
    body: '{"id":1,"secondId":1}'
  }
],
[
  'http://localhost:1111/workouts/1',
  {
    credentials: 'same-origin',
    headers: [Object],
    method: 'PATCH',
    body: '{"name":"sample name"}'
  }
]
] POST

Improve failure messages for toHaveLastFetched

I've used fetch-mock before but just installed fetch-mock-jest to try it out and provide some feedback :)

I'm doing this sort of thing in my tests:

expect(fetchMock).toHaveLastFetched({
  url: "/ownerships",
  body: {
    paint_id: "V76-517",
    quantity: 1
  }
})

I was expecting this to pass, but it didn't. The failure message I get is:

Last call to fetch should have had a URL of [object Object]

This made it quite tricky to work out what was actually going on, I had to use console.log(fetchMock.calls()) to see the call that was made and discovered that the wrong quantity was being sent:

[
  [
    '/ownerships',
    {
      method: 'POST',
      body: '{"paint_id":"V76-517","quantity":1}',
      credentials: 'same-origin',
      headers: [Object]
    },
    request: undefined,
    identifier: '/ownerships',
    isUnmatched: undefined
  ]
]

I think it would be really great if the toHaveLastFetched matcher could inspect the arguments it received and then respond with a corresponding output.

For example:

expect(fetchMock).toHaveLastFetched("/ownerships")

# Fails with
Last call to fetch should have had a URL of "/ownerships" but was "/owner_ships"

If toHaveLastFetched is called with an object literal, maybe the corresponding keys could be pulled from the resulting request and then nicely diffed so the user knows exactly what went wrong.

I'm going to keep playing, thanks for listening and for all of your hard work on fetch-mock :)

Doesn't play nice with jest.resetAllMocks()

As the fetch mock is made up of a jest.fn() married to our own implementation, resetAllMocks has the effect of unset half the mock, or something like that. Not quite clear what's going on , but it's annoying and makes the library confusing and almost unusable

Feature request: Treat warnings as errors

If an unexpected call occurs to the mock, I want my tests to fail.
It would be great if there was some MockBehavior.Strict mode, that does not do console.warn but throws an error instead.

sandbox() has the wrong type definition

sandbox() has a type from FetchMockJest, but also has a more-restrictive type from FetchMockStatic. Typescript calculates the intersection of these types, which causes the return type to drop the jest.MockInstance<Response, MockCall> designation.

How to configurate your library for typescript tests? (ts7016)

I am using ts-jest & want to mock fetch responses (for browser code).

First of all, after installing fetch-mock-jest, in jest setup file I should write
global.fetchMock = require('fetch-mock-jest');
is it right or it should be global.fetch = require('fetch-mock-jest').sandbox();?

In ts tests I can't write global.fetchMock or fetchMock without global declaring
or default importing import fetchMock from 'fetch-mock-jest';
But if I am doing such things, why I need to make changes in jest setup script?

Moreover, If I import fetchMock in test, eslint show me suggestion:
Could not find a declaration file for module 'fetch-mock-jest'. ... implicitly has an 'any' type
Try `npm install @types/fetch-mock-jest` if it exists or add a new declaration (.d.ts) file containing `declare module 'fetch-mock-jest'; (ts7016)

Can you provide d.ts file for using typed fetchMock methods?

Conflict with `bottleneck` library?

We have been using fetch-mock-jest to test that our client library is being called - and being called the right number of times with the expected parameters.

It was working perfectly when our client library, which contains rate limiting, was using the p-ratelimit library.
However, when we move to the bottleneck rate limiting library we see testing errors.

Previously when we ran the following test we would see that the url had been called:

		mockFetch.patch(url, 200);
		lockPatch(type, code, payload, query);
		expect(mockFetch.called(url)).toBe(true);

Now, when bottleneck is being used we get a false response to the called(url) check.
Further. inspection of the mockFetch results - by using the calls() function - indicates that p-ratelimit allows a full set of expected url calls to be recorded whereas bottleneck causes the url list to be empty.

We have included logging commands in our current library and can confirm both p-ratelimit and bottleneck DO both run the same set url fetch requests.

Can't see TS typings for this library

It seems the Typescript types are well defined for the fetch-mock library. However, I can't seem to find typings for this wrapper library anywhere. Could you please point me in the right direction?

when using delay and jest modern fakeTimers it seems to be using a real delay

I was trying to introduce a "delay" on the processing for the response so I used the { delay } option. But noticed my timings are getting randomized.

Upon closer inspection it seemed that there was a real delay once I increased the amount of time I was processing. So it is not respecting the modern jest.useFakeTimers

Ideally I was hoping it will use the setTimeout that is provided by jest so I can control the behaviour, but it is using the real thing.

`headers` are not matched strictly

Hello I noticed that when using toHaveFetched(url, { headers: {} }), it will always pass no matter what headers are passed but it should pass only if no headers are passed

    fetchMock.get('/api', { body: {} })
// custom wrapper around fetch
    await api.get('2')
    expect(fetchMock).toHaveFetched('/api/2', {
      headers: {
        // no Accept
        Accept: 'application/json'
        // 'Content-Type': 'application/json',
      },
    })

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.