-
Notifications
You must be signed in to change notification settings - Fork 355
docs: Added example with TypeScript, Jest and Fetch #440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
offirgolan
merged 8 commits into
Netflix:master
from
justsml:DL/add-example-typescript-jest-fetch
Apr 4, 2022
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
75783ec
docs: Added example code & comments on correct usage.
justsml 62cb76c
docs: Remove incomplete notes.
justsml 9a23fa4
chore: remove unnecessary dotfiles.
justsml ede513e
docs: Updated docs site
justsml 4bf2fe3
Remove comments
justsml 08c4609
Remove comments
justsml e5b2f62
refactor: Cleaning up POLLY_MODE logic
justsml cbfc69f
Merge branch 'DL/add-example-typescript-jest-fetch' of github.com:jus…
justsml File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
191 changes: 191 additions & 0 deletions
191
...t-node-fetch/__recordings__/github-api-client_2139812550/getUser_1648904580/recording.har
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,191 @@ | ||
| { | ||
| "log": { | ||
| "_recordingName": "github-api client/getUser", | ||
| "creator": { | ||
| "comment": "persister:fs", | ||
| "name": "Polly.JS", | ||
| "version": "5.1.1" | ||
| }, | ||
| "entries": [ | ||
| { | ||
| "_id": "daab17694c1a59a0f3781977d2bf32d7", | ||
| "_order": 0, | ||
| "cache": {}, | ||
| "request": { | ||
| "bodySize": 0, | ||
| "cookies": [], | ||
| "headers": [ | ||
| { | ||
| "_fromType": "array", | ||
| "name": "accept", | ||
| "value": "application/json+vnd.github.v3.raw" | ||
| }, | ||
| { | ||
| "_fromType": "array", | ||
| "name": "content-type", | ||
| "value": "application/json" | ||
| }, | ||
| { | ||
| "_fromType": "array", | ||
| "name": "user-agent", | ||
| "value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" | ||
| }, | ||
| { | ||
| "_fromType": "array", | ||
| "name": "accept-encoding", | ||
| "value": "gzip,deflate" | ||
| }, | ||
| { | ||
| "_fromType": "array", | ||
| "name": "connection", | ||
| "value": "close" | ||
| }, | ||
| { | ||
| "name": "host", | ||
| "value": "api.github.com" | ||
| } | ||
| ], | ||
| "headersSize": 269, | ||
| "httpVersion": "HTTP/1.1", | ||
| "method": "GET", | ||
| "queryString": [], | ||
| "url": "https://api.github.com/users/netflix" | ||
| }, | ||
| "response": { | ||
| "bodySize": 525, | ||
| "content": { | ||
| "_isBinary": true, | ||
| "mimeType": "application/json; charset=utf-8", | ||
| "size": 525, | ||
| "text": "[\"1f8b080000000000000395935f6f9b3014c5bf0af2338981aceb8a146dd2fe5493d666d25aa9ca4b64c081bb1adbb20d2945fdeebb06b2647998c41360dddfb987eb7b7a2254\",\"0992a4e49ebbbd8017121228487a13afaede5f8744aa82effc01b9fbf2b5db3cdf74dbe45bc39e7455dc8a36fbfdfc72f7fa98dc1fd66b0459cb1c33bbc608acaf9cd336a5743cb4cb125cd5648de52657d271e996b9aa6943c74e1fdbf53b5428cda431b4c4830b2d0d93ce08a398a527e395abc545f7b1eb507daadb2b21d401d94babff91a77f217435be832ce70b20d453e52a8e7342fb6ffea7c1ba595606a0a7fe8177e3252cceddf0628e9d09413307893e7a6ab856835693d9dc8076a0e42c5bff8028a44cc924bcb2d942085ae4bda15906060041dee27acd2247a2a7da40cbf2ce8fc1f09c438b339daf7681a298eb34c785de9c4dc44f1a1cdfb1a2f6f9db336139e68dd5be70dad530f82ef32556e2fe6a263b92ca4688906418da296298303926f7980c501409a1f261f058f643d9e0963965c3e03313b0574602f363aa19f8a44ebcb2f6d3510afb61410586b34ca0a1a92da893b760a3b90c7ea9c6e43cf82998435d0fb90338376df7f83723ac9b4c40be1bef284da20f21998e8675266974cc1506f3ec0b03337ce5e8c5e17530871e92288e17d1f5225e3d24118aa551bcc5de8d2ece6b926811278b287948927415a7abab2d79fb03b458ebc7f1040000\"]" | ||
| }, | ||
| "cookies": [], | ||
| "headers": [ | ||
| { | ||
| "name": "server", | ||
| "value": "GitHub.com" | ||
| }, | ||
| { | ||
| "name": "date", | ||
| "value": "Sat, 19 Feb 2022 05:56:54 GMT" | ||
| }, | ||
| { | ||
| "name": "content-type", | ||
| "value": "application/json; charset=utf-8" | ||
| }, | ||
| { | ||
| "name": "cache-control", | ||
| "value": "public, max-age=60, s-maxage=60" | ||
| }, | ||
| { | ||
| "name": "vary", | ||
| "value": "Accept, Accept-Encoding, Accept, X-Requested-With" | ||
| }, | ||
| { | ||
| "name": "etag", | ||
| "value": "W/\"e7c5ada389fe724c41d8b2248ede8e368c0fdd159f907ca79d9c0a78fa3344cb\"" | ||
| }, | ||
| { | ||
| "name": "last-modified", | ||
| "value": "Wed, 02 Dec 2020 22:31:35 GMT" | ||
| }, | ||
| { | ||
| "name": "x-github-media-type", | ||
| "value": "github.v3; format=vnd.github.v3.raw" | ||
| }, | ||
| { | ||
| "name": "access-control-expose-headers", | ||
| "value": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" | ||
| }, | ||
| { | ||
| "name": "access-control-allow-origin", | ||
| "value": "*" | ||
| }, | ||
| { | ||
| "name": "strict-transport-security", | ||
| "value": "max-age=31536000; includeSubdomains; preload" | ||
| }, | ||
| { | ||
| "name": "x-frame-options", | ||
| "value": "deny" | ||
| }, | ||
| { | ||
| "name": "x-content-type-options", | ||
| "value": "nosniff" | ||
| }, | ||
| { | ||
| "name": "x-xss-protection", | ||
| "value": "0" | ||
| }, | ||
| { | ||
| "name": "referrer-policy", | ||
| "value": "origin-when-cross-origin, strict-origin-when-cross-origin" | ||
| }, | ||
| { | ||
| "name": "content-security-policy", | ||
| "value": "default-src 'none'" | ||
| }, | ||
| { | ||
| "name": "content-encoding", | ||
| "value": "gzip" | ||
| }, | ||
| { | ||
| "name": "x-ratelimit-limit", | ||
| "value": "60" | ||
| }, | ||
| { | ||
| "name": "x-ratelimit-remaining", | ||
| "value": "59" | ||
| }, | ||
| { | ||
| "name": "x-ratelimit-reset", | ||
| "value": "1645253814" | ||
| }, | ||
| { | ||
| "name": "x-ratelimit-resource", | ||
| "value": "core" | ||
| }, | ||
| { | ||
| "name": "x-ratelimit-used", | ||
| "value": "1" | ||
| }, | ||
| { | ||
| "name": "accept-ranges", | ||
| "value": "bytes" | ||
| }, | ||
| { | ||
| "name": "content-length", | ||
| "value": "525" | ||
| }, | ||
| { | ||
| "name": "x-github-request-id", | ||
| "value": "F38D:0289:2486BB0:45D7297:621086A6" | ||
| }, | ||
| { | ||
| "name": "connection", | ||
| "value": "close" | ||
| } | ||
| ], | ||
| "headersSize": 1283, | ||
| "httpVersion": "HTTP/1.1", | ||
| "redirectURL": "", | ||
| "status": 200, | ||
| "statusText": "OK" | ||
| }, | ||
| "startedDateTime": "2022-02-19T05:56:54.149Z", | ||
| "time": 454, | ||
| "timings": { | ||
| "blocked": -1, | ||
| "connect": -1, | ||
| "dns": -1, | ||
| "receive": 0, | ||
| "send": 0, | ||
| "ssl": -1, | ||
| "wait": 454 | ||
| } | ||
| } | ||
| ], | ||
| "pages": [], | ||
| "version": "1.2" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { Config } from "@jest/types"; | ||
|
|
||
| const config: Config.InitialOptions = { | ||
| rootDir: ".", | ||
| preset: "ts-jest", | ||
| testEnvironment: "setup-polly-jest/jest-environment-jsdom", | ||
| verbose: true, | ||
| testPathIgnorePatterns: ["node_modules", "dist"], | ||
| resetModules: true, | ||
| globals: { | ||
| "ts-jest": { | ||
| useESM: true, | ||
| }, | ||
| }, | ||
| transform: { }, | ||
| }; | ||
|
|
||
| export default config; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| { | ||
| "name": "typescript-jest-node-fetch", | ||
| "version": "1.0.0", | ||
| "private": true, | ||
| "main": "./dist/index.js", | ||
| "type": "commonjs", | ||
| "exports": "./dist/index.js", | ||
| "scripts": { | ||
| "test": "jest --runInBand", | ||
| "test:record": "POLLY_MODE=record jest --runInBand --verbose" | ||
| }, | ||
| "keywords": [ | ||
| "pollyjs", | ||
| "test-mocking", | ||
| "jest", | ||
| "node", | ||
| "typescript", | ||
| "fetch" | ||
| ], | ||
| "author": "", | ||
| "license": "Apache-2.0", | ||
| "dependencies": { | ||
| "node-fetch": "^2.6.6" | ||
| }, | ||
| "devDependencies": { | ||
| "@pollyjs/adapter-fetch": "^5.1.1", | ||
| "@pollyjs/adapter-node-http": "^5.1.1", | ||
| "@pollyjs/core": "^5.1.1", | ||
| "@pollyjs/node-server": "^5.1.1", | ||
| "@pollyjs/persister-fs": "^5.1.1", | ||
| "@types/jest": "^26.0.0", | ||
| "@types/node": "^16.11.11", | ||
| "@types/node-fetch": "^2.5.12", | ||
| "@types/pollyjs__adapter": "^4.3.1", | ||
| "@types/pollyjs__adapter-fetch": "^2.0.1", | ||
| "@types/pollyjs__adapter-node-http": "^2.0.1", | ||
| "@types/pollyjs__core": "^4.3.3", | ||
| "@types/pollyjs__persister": "^4.3.1", | ||
| "@types/pollyjs__persister-fs": "^2.0.1", | ||
| "@types/pollyjs__utils": "^2.6.1", | ||
| "@types/setup-polly-jest": "^0.5.1", | ||
| "jest": "^26.6.0", | ||
| "nodemon": "^2.0.15", | ||
| "setup-polly-jest": "^0.10.0", | ||
| "ts-jest": "^26.5.6", | ||
| "ts-node": "^10.4.0", | ||
| "typescript": "^4.5.2" | ||
| } | ||
| } |
31 changes: 31 additions & 0 deletions
31
examples/typescript-jest-node-fetch/src/github-api.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| /** @jest-environment setup-polly-jest/jest-environment-node */ | ||
| import autoSetupPolly from './utils/auto-setup-polly'; | ||
| import { getUser } from './github-api'; | ||
|
|
||
| describe('github-api client', () => { | ||
| let pollyContext = autoSetupPolly(); | ||
|
|
||
| beforeEach(() => { | ||
| // Intercept /ping healthcheck requests (example) | ||
| pollyContext.polly.server | ||
| .any("/ping") | ||
| .intercept((req, res) => void res.sendStatus(200)); | ||
| }); | ||
|
|
||
| it('getUser', async () => { | ||
| const user: any = await getUser('netflix'); | ||
| expect(typeof user).toBe('object'); | ||
| expect(user?.login).toBe('Netflix'); | ||
| }); | ||
|
|
||
| it('getUser: custom interceptor', async () => { | ||
| expect.assertions(1); | ||
| pollyContext.polly.server | ||
| .get('https://api.github.com/users/failing_request_trigger') | ||
| .intercept((req, res) => void res.sendStatus(500)); | ||
|
|
||
| await expect(getUser('failing_request_trigger')).rejects.toThrow( | ||
| 'Http Error: 500' | ||
| ); | ||
| }); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import fetch from "node-fetch"; | ||
| import type { Response } from "node-fetch"; | ||
|
|
||
| export const getUser = async (username: string): Promise<unknown> => { | ||
| return fetch(`https://api.github.com/users/${username}`, { | ||
| headers: { | ||
| "Accept": "application/json+vnd.github.v3.raw", | ||
| "Content-type": "application/json", | ||
| }, | ||
| }) | ||
| .then(checkErrorAndReturnJson); | ||
| }; | ||
|
|
||
| function checkErrorAndReturnJson(response: Response) { | ||
| return response.ok | ||
| ? response.json() | ||
| : Promise.reject(new Error(`Http Error: ${response.status}`)); | ||
| } |
48 changes: 48 additions & 0 deletions
48
examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import path from "path"; | ||
| import { setupPolly } from "setup-polly-jest"; | ||
| import { Polly, PollyConfig } from "@pollyjs/core"; | ||
| import NodeHttpAdapter from "@pollyjs/adapter-node-http"; | ||
| import FSPersister from "@pollyjs/persister-fs"; | ||
|
|
||
| Polly.register(NodeHttpAdapter); | ||
| Polly.register(FSPersister); | ||
|
|
||
| let recordIfMissing = true; | ||
| let mode: PollyConfig['mode'] = 'replay'; | ||
|
|
||
| switch (process.env.POLLY_MODE) { | ||
| case 'record': | ||
| mode = 'record'; | ||
| break; | ||
| case 'replay': | ||
| mode = 'replay'; | ||
| break; | ||
| case 'offline': | ||
| mode = 'replay'; | ||
| recordIfMissing = false; | ||
| break; | ||
| } | ||
|
|
||
| export default function autoSetupPolly() { | ||
| /** | ||
| * This persister can be adapted for both Node.js and Browser environments. | ||
| * | ||
| * TODO: Customize your config. | ||
| */ | ||
| return setupPolly({ | ||
| // 🟡 Note: In node, most `fetch` like libraries use the http/https modules. | ||
| // `node-fetch` is handled by `NodeHttpAdapter`, NOT the `FetchAdapter`. | ||
| adapters: ["node-http"], | ||
| mode, | ||
| recordIfMissing, | ||
| flushRequestsOnStop: true, | ||
| logging: false, | ||
| recordFailedRequests: true, | ||
| persister: "fs", | ||
| persisterOptions: { | ||
| fs: { | ||
| recordingsDir: path.resolve(__dirname, "../../__recordings__"), | ||
| }, | ||
| }, | ||
| }); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm testing this library in our test suite. My feeling is that Polly should be as automatic as possible and devs shouldn't have to think about it (unless they want to mock a request). I found that I could set up Polly without having to add anything manually to tests using this:
This way
pollyContextis magically available in any test.Obviously this is a little bit specific, but what do you think about this approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love where you're going @mcmire - I think Polly is 🔥 when it's transparent, so your code doesn't change depending on if you want to mock or not.
I was going to include something similar to this pattern! The reason I didn't is because I think an opt-in design can meet more use cases.
As it still allows you to wire it up in
setupFilesAfterEnvscripts:Maybe another example or some comments in the README is warranted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah that's a fair point. This technique is also useful if you're slowly introducing Polly into a test suite, I'd imagine. In that case, an extra example would be nice, but not necessary.