diff --git a/README.md b/README.md index 956924f..f945afd 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ If you are using [Create-React-App](https://github.com/facebookincubator/create- ### Functions Instead of passing body, it is also possible to pass a function that returns a promise. -The promise should resolve with a string or an object containing body and init props +The promise should resolve with a string or an object containing body and init props, or a `Response` object. i.e: @@ -186,6 +186,8 @@ i.e: fetch.mockResponse(() => callMyApi().then(res => ({ body: 'ok' }))) // OR fetch.mockResponse(() => callMyApi().then(res => 'ok')) +// OR +fetch.mockResponse(() => callMyApi().then(res => new Response('foo'))) ``` The function may take an optional "request" parameter of type `http.Request`: diff --git a/src/index.js b/src/index.js index 4ac478d..a40570c 100644 --- a/src/index.js +++ b/src/index.js @@ -17,6 +17,10 @@ if (typeof DOMException === 'undefined') { const ActualResponse = Response function responseWrapper(body, init) { + if (body instanceof ActualResponse) { + return body; + } + if ( body && typeof body.constructor === 'function' && diff --git a/tests/test.js b/tests/test.js index 5f0cea0..534badd 100644 --- a/tests/test.js +++ b/tests/test.js @@ -1,3 +1,4 @@ +const { StringDecoder } = require('string_decoder'); const { APIRequest, APIRequest2, defaultRequestUri, request } = require('./api') describe('testing mockResponse and alias once', () => { @@ -358,6 +359,24 @@ describe('request', () => { fetch('https://bar', {}).then((response) => response.headers.get('ding')) ).resolves.toEqual('dang') }) + + it('accepts a promise that resolves with a repsonse', () => { + fetch.mockResponseOnce(() => Promise.resolve(new Response(Buffer.from('foo')))) + return expect( + fetch('https://bar', {}) + .then((response) => response.arrayBuffer()) + .then((arrayBuffer) => new StringDecoder('utf8').write(new Uint8Array(arrayBuffer))) + ).resolves.toEqual('foo') + }) + + it('accepts a response', () => { + fetch.mockResponseOnce(new Response(Buffer.from('foo'))) + return expect( + fetch('https://bar', {}) + .then((response) => response.arrayBuffer()) + .then((arrayBuffer) => new StringDecoder('utf8').write(new Uint8Array(arrayBuffer))) + ).resolves.toEqual('foo') + }) }) describe('conditional mocking', () => { diff --git a/types/index.d.ts b/types/index.d.ts index 22ae47b..174330b 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -23,15 +23,18 @@ export interface FetchMock // Response mocking mockResponse(fn: MockResponseInitFunction): FetchMock; mockResponse(response: string, responseInit?: MockParams): FetchMock; + mockResponse(response: Response): FetchMock; mockResponseOnce(fn: MockResponseInitFunction): FetchMock; mockResponseOnce(response: string, responseInit?: MockParams): FetchMock; + mockResponseOnce(response: Response): FetchMock; // alias for mockResponseOnce once(fn: MockResponseInitFunction): FetchMock; + once(response: Response): FetchMock; once(url: string, responseInit?: MockParams): FetchMock; - mockResponses(...responses: Array): FetchMock; + mockResponses(...responses: Array): FetchMock; // Error/Reject mocking mockReject(error?: ErrorOrFunction): FetchMock; @@ -45,36 +48,47 @@ export interface FetchMock doMock(fn?: MockResponseInitFunction): FetchMock; doMock(response: string, responseInit?: MockParams): FetchMock; + doMock(response: Response): FetchMock; doMockOnce(fn?: MockResponseInitFunction): FetchMock; doMockOnce(response: string, responseInit?: MockParams): FetchMock; + doMockOnce(response: Response): FetchMock; // alias for doMockOnce mockOnce(fn?: MockResponseInitFunction): FetchMock; mockOnce(response: string, responseInit?: MockParams): FetchMock; + mockOnce(response: Response): FetchMock; doMockIf(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock; doMockIf(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock; + doMockIf(urlOrPredicate: UrlOrPredicate, response: Response) : FetchMock; // alias for doMockIf mockIf(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock; mockIf(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock; + mockIf(urlOrPredicate: UrlOrPredicate, response: Response) : FetchMock; doMockOnceIf(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock; doMockOnceIf(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock; + doMockOnceIf(urlOrPredicate: UrlOrPredicate, response: Response) : FetchMock; // alias for doMocKOnceIf mockOnceIf(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock; mockOnceIf(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock; + mockOnceIf(urlOrPredicate: UrlOrPredicate, response: Response) : FetchMock; dontMock(fn?: MockResponseInitFunction): FetchMock; dontMock(response: string, responseInit?: MockParams): FetchMock; + dontMock(response: Response): FetchMock; dontMockOnce(fn?: MockResponseInitFunction): FetchMock; dontMockOnce(response: string, responseInit?: MockParams): FetchMock; + dontMockOnce(response: Response): FetchMock; dontMockIf(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock; dontMockIf(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock; + dontMockIf(urlOrPredicate: UrlOrPredicate, response: Response): FetchMock; dontMockOnceIf(urlOrPredicate: UrlOrPredicate, fn?: MockResponseInitFunction): FetchMock; dontMockOnceIf(urlOrPredicate: UrlOrPredicate, response: string, responseInit?: MockParams): FetchMock; + dontMockOnceIf(urlOrPredicate: UrlOrPredicate, response: Response): FetchMock; resetMocks(): void; enableMocks(): void; @@ -98,7 +112,7 @@ export interface MockResponseInit extends MockParams { export type ErrorOrFunction = Error | ((...args: any[]) => Promise); export type UrlOrPredicate = string | RegExp | ((input: Request) => boolean); -export type MockResponseInitFunction = (request: Request) => MockResponseInit | string | Promise; +export type MockResponseInitFunction = (request: Request) => MockResponseInit | string | Response | Promise; // alias of fetchMock.enableMocks() for ES6 import syntax to not clash with other libraries export function enableFetchMocks(): void; diff --git a/types/test.ts b/types/test.ts index f401788..ef0e67d 100644 --- a/types/test.ts +++ b/types/test.ts @@ -8,8 +8,10 @@ fetchMock.mockResponse(JSON.stringify({foo: "bar"}), { ] }); fetchMock.mockResponse(JSON.stringify({foo: "bar"}), {}); +fetchMock.mockResponse(new Response('foo')); fetchMock.mockResponse(someAsyncHandler); fetchMock.mockResponse(someAsyncStringHandler); +fetchMock.mockResponse(someAsyncResponseHandler) fetchMock.mockResponseOnce(JSON.stringify({foo: "bar"})); fetchMock.mockResponseOnce(JSON.stringify({foo: "bar"}), { @@ -19,8 +21,10 @@ fetchMock.mockResponseOnce(JSON.stringify({foo: "bar"}), { ] }); fetchMock.mockResponseOnce(JSON.stringify({foo: "bar"}), {}); +fetchMock.mockResponseOnce(new Response('foo')); fetchMock.mockResponseOnce(someAsyncHandler); fetchMock.mockResponseOnce(someAsyncStringHandler); +fetchMock.mockResponseOnce(someAsyncResponseHandler) fetchMock.once(JSON.stringify({foo: "bar"})); fetchMock.once(JSON.stringify({foo: "bar"}), { @@ -30,7 +34,9 @@ fetchMock.once(JSON.stringify({foo: "bar"}), { ] }); fetchMock.once(JSON.stringify({foo: "bar"}), {}); +fetchMock.once(new Response('foo')); fetchMock.once(someAsyncHandler); +fetchMock.once(someAsyncResponseHandler); fetchMock.mockResponses(JSON.stringify({}), JSON.stringify({foo: "bar"})); fetchMock.mockResponses(someAsyncHandler, someAsyncHandler); @@ -38,11 +44,14 @@ fetchMock.mockResponses(JSON.stringify({}), someAsyncHandler); fetchMock.mockResponses(someAsyncHandler, JSON.stringify({})); fetchMock.mockResponses(someAsyncHandler); fetchMock.mockResponses([JSON.stringify({foo: "bar"}), {status: 200}]); +fetchMock.mockResponses(new Response('foo')) +fetchMock.mockResponses(JSON.stringify({}), new Response('foo')) fetchMock.mockResponses( someSyncHandler, someAsyncHandler, someSyncStringHandler, someAsyncStringHandler, + someAsyncResponseHandler, [JSON.stringify({foo: "bar"}), {status: 200}] ); @@ -105,6 +114,10 @@ function someSyncStringHandler(): string { return JSON.stringify({foo: "bar"}); } +async function someAsyncResponseHandler(): Promise { + return new Response(Buffer.from('foo')); +} + enableFetchMocks(); disableFetchMocks(); fm.enableMocks();