Skip to content

Commit ef6f09c

Browse files
authored
Expose .calls with normalizeRequest (#8)
* Add safer alternative to .calls * Fix handling of aborted requests * Add missing return (I forgor) * Remove vscode settings file * Improve documentation
1 parent 8574911 commit ef6f09c

File tree

4 files changed

+46
-12
lines changed

4 files changed

+46
-12
lines changed

README.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ describe('testing api', () => {
273273
expect(res.data).toEqual('12345');
274274

275275
//assert on the times called and arguments given to fetch
276-
expect(fetch.mock.calls.length).toEqual(1);
277-
expect(fetch.mock.calls[0][0]).toEqual('https://google.com');
276+
expect(fetch.requests().length).toEqual(1);
277+
expect(fetch.requests()[0].url).toEqual('https://google.com/');
278278
});
279279
});
280280
```
@@ -613,12 +613,13 @@ describe('getYear action creator', () => {
613613

614614
### Using `fetch.mock` to inspect the mock state of each fetch call
615615

616-
`fetch.mock` by default uses [Vitest's mocking functions](https://vitest.dev/api/#mockinstance-properties). Therefore
616+
`fetch.mock` by default uses [Vitest's mocking functions](https://vitest.dev/api/mock.html). Therefore
617617
you can make assertions on the mock state. In this example we have an arbitrary function that makes a different fetch
618618
request based on the argument you pass to it. In our test, we run Vitest's `beforeEach()` and make sure to reset our
619-
mock before each `it()` block as we will make assertions on the arguments we are passing to `fetch()`. The most uses
620-
property is the `fetch.mock.calls` array. It can give you information on each call, and their arguments which you can
621-
use for your `expect()` calls. Vitest also comes with some nice aliases for the most used ones.
619+
mock before each `it()` block as we will make assertions on the arguments we are passing to `fetch()`. Then we use the
620+
`fetch.requests()` function to give us a history of all non-aborted requests (normalized) that were made. It can give you
621+
information on each call, and their arguments which you can use for your `expect()` calls. Vitest also comes with some
622+
nice aliases for the most used ones.
622623

623624
```js
624625
// api.js
@@ -649,25 +650,26 @@ describe('testing api', () => {
649650
fetch.mockResponse(JSON.stringify({ secret_data: '12345' }));
650651
APIRequest();
651652

652-
expect(fetch.mock.calls.length).toEqual(1);
653-
expect(fetch.mock.calls[0][0]).toEqual('https://google.com');
653+
// there was one request, which was not aborted
654+
expect(fetch.requests().length).toEqual(1);
655+
expect(fetch.requests()[0].url).toEqual('https://google.com/');
654656
});
655657

656658
it('calls facebook', () => {
657659
fetch.mockResponse(JSON.stringify({ secret_data: '12345' }));
658660
APIRequest('facebook');
659661

660-
expect(fetch.mock.calls.length).toEqual(2);
661-
expect(fetch.mock.calls[0][0]).toEqual('https://facebook.com/someOtherResource');
662-
expect(fetch.mock.calls[1][0]).toEqual('https://facebook.com');
662+
expect(fetch.requests().length).toEqual(2);
663+
expect(fetch.requests()[0].url).toEqual('https://facebook.com/someOtherResource');
664+
expect(fetch.requests()[1].url).toEqual('https://facebook.com/');
663665
});
664666

665667
it('calls twitter', () => {
666668
fetch.mockResponse(JSON.stringify({ secret_data: '12345' }));
667669
APIRequest('twitter');
668670

669671
expect(fetch).toBeCalled(); // alias for expect(fetch.mock.calls.length).toEqual(1);
670-
expect(fetch).toBeCalledWith('https://twitter.com'); // alias for expect(fetch.mock.calls[0][0]).toEqual();
672+
expect(fetch.requests().map(v => v.url)).toContain('https://twitter.com/');
671673
});
672674
});
673675
```

src/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,19 @@ export default function createFetchMocker(vi) {
236236
return fetch;
237237
};
238238

239+
fetch.requests = () => {
240+
const requests = [];
241+
fetch.mock.calls.forEach((call) => {
242+
try {
243+
let req = normalizeRequest(call[0], call[1]);
244+
requests.push(req);
245+
} catch(e) {
246+
// ignore
247+
}
248+
});
249+
return requests;
250+
};
251+
239252
fetch.resetMocks = () => {
240253
fetch.mockReset();
241254
isMocking.mockReset();

tests/api.test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ describe('testing mockResponse and alias once', () => {
1414
expect(response).toEqual({ secret_data: 'abcde' });
1515
expect(fetch.mock.calls.length).toEqual(1);
1616
expect(fetch.mock.calls[0][0]).toEqual('https://google.com');
17+
expect(fetch.requests().length).toEqual(1);
18+
expect(fetch.requests()[0].url).toEqual('https://google.com/');
1719
});
1820

1921
it('mocks a response with chaining', async () => {
@@ -53,6 +55,7 @@ describe('testing mockResponse and alias once', () => {
5355
expect(fetch.mock.calls.length).toEqual(2);
5456

5557
expect(fetch.mock.calls[0][0]).toEqual('https://facebook.com/someOtherResource');
58+
expect(fetch.requests()[0].url).toEqual('https://facebook.com/someOtherResource');
5659
expect(fetch.mock.calls[1][0]).toEqual('https://facebook.com');
5760
});
5861

@@ -66,6 +69,16 @@ describe('testing mockResponse and alias once', () => {
6669
expect(fetch.mock.calls[0][0]).toEqual(new URL('https://instagram.com'));
6770
});
6871

72+
it('returns normalized requests', async () => {
73+
fetch.mockResponseOnce(JSON.stringify({ secret_data: 'abcde' }, { status: 200 }));
74+
75+
const response = await APIRequest('instagram');
76+
77+
expect(response).toEqual({ secret_data: 'abcde' });
78+
expect(fetch.requests().length).toEqual(1);
79+
expect(fetch.requests()[0].method).toEqual("GET");
80+
});
81+
6982
it('supports an object with a stringifier', async () => {
7083
fetch.mockResponseOnce(JSON.stringify({ secret_data: 'abcde' }, { status: 200 }));
7184

types/index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ export interface FetchMock
110110

111111
dontMockOnceIf(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock;
112112
dontMockOnceIf(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock;
113+
114+
/**
115+
* Returns all the requests that have been made to the mocked fetch function.
116+
* Does not include aborted requests.
117+
*/
118+
requests(): Request[];
113119

114120
resetMocks(): void;
115121
enableMocks(): void;

0 commit comments

Comments
 (0)