wheresrhys / fetch-mock-jest

Jest wrapper for fetch-mock, a comprehensive stub for fetch
http://www.wheresrhys.co.uk/fetch-mock/
MIT License
60 stars 11 forks source link

Let fetchMock.mock() return scoped mock #17

Closed trixn86 closed 3 years ago

trixn86 commented 4 years ago

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?

wheresrhys commented 4 years ago

Sorry for the slow response.

I like the API idea, but it feels like a massive departure from the current implementation and probably difficult to achieve. Would require massive amounts of writing new tests for the library (or, rather, for fetch-mock) too.

So realistically I can't see it happening, but will keep it open in case I think of a way.

For fetch-mock there is an easier naming API coming soon probably

fetch.mock(url, response, 'my-name');
expect(fetchMock).toHaveFetchedTimes('my-name');

In fact, even now, you should be able to use 'my-name' instead of {name: 'my-name'} in assertions anyway