Comparing version 0.2.3 to 0.2.4
{ | ||
"name": "vi-fetch", | ||
"version": "0.2.3", | ||
"version": "0.2.4", | ||
"description": "Easiest way to mock fetch", | ||
@@ -24,7 +24,15 @@ "main": "./dist/index.js", | ||
"import": "./dist/setup.js", | ||
"types": "./dist/global.d.ts" | ||
"types": "./global.d.ts" | ||
} | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/sheremet-va/vi-fetch.git" | ||
}, | ||
"author": "sheremet-va", | ||
"license": "ISC", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/sheremet-va/vi-fetch/issues" | ||
}, | ||
"homepage": "https://github.com/sheremet-va/vi-fetch#readme", | ||
"dependencies": { | ||
@@ -31,0 +39,0 @@ "query-string": "^7.0.1", |
298
README.md
@@ -7,297 +7,3 @@ # vi-fetch | ||
## Installing | ||
```sh | ||
# with npm | ||
npm install -D vi-fetch | ||
# with pnpm | ||
pnpm install -D vi-fetch | ||
# with yarn | ||
yarn install -D vi-fetch | ||
``` | ||
## Usage | ||
### Setup | ||
Before using mock API, you need to set up fetch mock. To do this, import `vi-fetch/setup` in your setup file: | ||
```ts | ||
import 'vi-fetch/setup'; | ||
``` | ||
If `fetch` is located on another object, you can manually setup it with `prepareFetch` function, imported from `vi-fetch`: | ||
```ts | ||
import { prepareFetch } from 'vi-fetch'; | ||
prepareFetch(globalThis, 'fetchNode'); | ||
``` | ||
### Mock Instance | ||
Calling `fetch` in browser can resolve in multiple situations: | ||
- resolve with `ok: true` | ||
- resolve with `ok: false` | ||
- throw `TypeError` if something is wrong | ||
Usually we know the API endpoint and need to test only these three situations, and `vi-fetch` provides a wrapper around `fetch` to make it easy. | ||
Use `mockApi` function to define `fetch` behavior. Aliases for popular methods are available: `mockGet`, `mockPost`, `mockPut`, `mockPatch`, `mockDelete`. | ||
> You can ignore query string when mocking, if you provide last argument as `false`. By default, query string is necessary. | ||
#### willResolve | ||
To mock `fetch` with `ok: true`, you can use `willResolve/willResolveOnce` methods. | ||
- By default, `willResolve` will resolve to `{}`, if no body is specified. | ||
- By default, `willResolve` will return `status: 200`. You can override it with second argument. | ||
```ts | ||
import { test, expect } from 'vitest'; | ||
import { mockGet } from 'vi-fetch'; | ||
import { renderApplesTable } from '../src/ApplesTable'; | ||
test('apples endpoint was called', async () => { | ||
// or just "/apples" if you configure baseUrl | ||
const mock = mockGet('https://api.com/v1/apples').willResolve([ | ||
{ count: 33 }, | ||
]); | ||
await renderApplesTable(); | ||
expect(mock).toHaveFetched(); | ||
}); | ||
``` | ||
#### willFail | ||
To mock `fetch` with `ok: false`, you can use `willFail/willFailOnce` methods. | ||
- By default, `willFail` will resolve to `{}`, if no body is specified. | ||
- By default, `willFail` will return `status: 500` and `statucCode: Internal error`. You can override it with second and third arguments. | ||
```ts | ||
import { test, expect } from 'vitest'; | ||
import { mockGet } from 'vi-fetch'; | ||
import { renderApplesTable } from '../src/ApplesTable'; | ||
test('apples endpoint was called', async () => { | ||
// or just "/apples" if you configure baseUrl | ||
const mock = mockGet('https://api.com/v1/apples').willFail( | ||
{ error: 'no apples' }, | ||
404 | ||
); | ||
await renderApplesTable(); | ||
expect(mock).toHaveFetched(); | ||
}); | ||
``` | ||
> Warning: calling `willFail` will override every other mock. | ||
#### willThrow | ||
If you have logic that depends on `fetch` throwing, you can test it with `willThrow/willThrowOnce` methods. | ||
`willThrow` requires `Error` object or a message. If `message` is specified, `fetch` will throw `TypeError`. | ||
```ts | ||
import { test, expect } from 'vitest'; | ||
import { mockGet } from 'vi-fetch'; | ||
import { renderApplesTable } from '../src/ApplesTable'; | ||
test('apples endpoint was called', async () => { | ||
// or just "/apples" if you configure baseUrl | ||
const mock = mockGet('https://api.com/v1/apples').willThrow('cors error'); | ||
await renderApplesTable(); | ||
expect(mock).toHaveFetched(); | ||
}); | ||
``` | ||
> Warning: calling `willThrow` will override every other mock. | ||
#### willDo | ||
If you want to do something when the `fetch` is invoking, you can use `willDo` method: | ||
```ts | ||
import { test, expect } from 'vitest'; | ||
import { mockGet } from 'vi-fetch'; | ||
import { renderApplesTable } from '../src/ApplesTable'; | ||
test('apples endpoint was called', async () => { | ||
// or just "/apples" if you configure baseUrl | ||
const mock = mockGet('https://api.com/v1/apples').willDo((url) => { | ||
if (url.searchParams.get('offset') > 2)) { | ||
return { body: [] }; | ||
} | ||
return { body: [{ count: 3 }] }; | ||
}); | ||
await renderApplesTable(); | ||
expect(mock).toHaveFetched(); | ||
}); | ||
``` | ||
> Warning: calling `willDo` will override every other mock. | ||
#### clear | ||
You can clear on implementation details with `clear` method. | ||
### Configuration | ||
To not repeat `baseUrl` every time you mock endpoint, you can configure it globally: | ||
```ts | ||
import { mockApi } from 'vi-fetch'; | ||
mockApi.setOptions({ | ||
baseUrl: 'https://api.com/v1', | ||
}); | ||
``` | ||
You can also create isolated `mockApi` with its own options to not collide with globals: | ||
```ts | ||
import { createMockApi } from 'vi-fetch'; | ||
import { test, expect } from 'vitest'; | ||
const { mockApi } = createMockApi({ baseUrl: 'https://api.com/v2' }); | ||
test('isolated', async () => { | ||
const mock = mockApi('GET', '/apples').willResolve(33); | ||
await fetch('http://api.com/v2/apples'); | ||
expect(mock).toHaveFetched(); | ||
}); | ||
``` | ||
You can ignore `queryString`, if it doesn't matter for you and then check it with `toHaveFetchedWithQuery`, if it's needed: | ||
```ts | ||
import { test, expect } from 'vitest'; | ||
import { mockGet } from 'vi-fetch'; | ||
test('apples endpoint was called', async () => { | ||
const mock = mockGet('https://api.com/v1/apples', false).willResolve([ | ||
{ count: 33 }, | ||
]); | ||
await fetch('https://api.com/v1/apples?count=5&offset=2'); | ||
expect(mock).toHaveFetched(); | ||
expect(mock).toHaveFetchedWithQuery({ count: 5, offset: 2 }); | ||
}); | ||
``` | ||
### Matchers | ||
Imagine we have a test with this setup: | ||
```ts | ||
import { expect, test } from 'vitest'; | ||
import { mockApi } from 'vi-fetch'; | ||
mockApi.setOptions({ baseUrl: 'https://api.com/v1' }); | ||
// usually you would call fetch inside your source code | ||
const callFetch = (url, options) => { | ||
return fetch('https://api.com/v1' + url, options); | ||
}; | ||
``` | ||
#### toHaveFetched | ||
If you want to check if `fetch` was called with appropriate URL and method, you can use `toHaveFetched`. | ||
```ts | ||
test('api was called', async () => { | ||
const mock = mockApi('GET', '/apples').willResolve({ | ||
count: 0, | ||
apples: [], | ||
}); | ||
await callFetch('/apples'); | ||
expect(mock).toHaveFetched(); | ||
}); | ||
``` | ||
#### toHaveFetchedTimes | ||
If you need to check if URL was called multiple times, you can use `toHaveFetchedTimes`. | ||
```ts | ||
test('api was called 3 times', async () => { | ||
const mock = mockApi('GET', '/apples', false).willResolve({ | ||
count: 0, | ||
apples: [], | ||
}); | ||
await callFetch('/apples'); | ||
await callFetch('/apples?offset=2'); | ||
await callFetch('/apples?offset=3'); | ||
expect(mock).toHaveFetchedTimes(3); | ||
}); | ||
``` | ||
#### toHaveFetchedWithBody | ||
If you need to check if URL was called with the specific body, you can use `toHaveFetchedWithBody/toHaveFetchedNthTimeWithBody`. | ||
```ts | ||
test('api was called with json', async () => { | ||
const mock = mockApi('POST', '/apples').willResolve({ | ||
count: 0, | ||
apples: [], | ||
}); | ||
await callFetch('/apples', { | ||
method: 'POST', | ||
body: '{ "foo": "baz" }', | ||
}); | ||
expect(mock).toHaveFetchedWithBody({ foo: 'baz' }); | ||
expect(mock).toHaveFetchedWithBody('{ "foo": "baz" }'); | ||
expect(mock).toHaveNthTimeFetchedWithBody(1, { foo: 'baz' }); | ||
}); | ||
``` | ||
#### toHaveFetchedWithQuery | ||
If you need to check if URL was called with the specific query string, you can use `toHaveFetchedWithQuery/toHaveFetchedNthTimeWithQuery`. | ||
```ts | ||
test('api was called with json', async () => { | ||
const mock = mockApi('GET', '/apples').willResolve({ | ||
count: 0, | ||
apples: [], | ||
}); | ||
await callFetch('/apples?count=5&offset=2'); | ||
expect(mock).toHaveFetchedWithQuery({ count: 5, offset: 2 }); | ||
expect(mock).toHaveFetchedWithQuery( | ||
new URLSearchParams({ count: '5', offset: '2' }) | ||
); | ||
expect(mock).toHaveFetchedWithQuery('count=5&offset=2'); | ||
expect(mock).toHaveFetchedNthTimeWithQuery(1, { count: 5, offset: 2 }); | ||
expect(mock).toHaveFetchedNthTimeWithQuery(1, 'count=5&offset=2'); | ||
}); | ||
``` | ||
> Support string, object or URLSearchParams | ||
## Docs | ||
Read **[full docs](https://github.com/sheremet-va/vi-fetch#readme)** on GitHub. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
0
1
0
25389
9