From 372542666ae753ed0736e36519c5c52439118b72 Mon Sep 17 00:00:00 2001 From: Matt Phillips Date: Tue, 6 Mar 2018 12:07:21 +0000 Subject: [PATCH 1/2] Add 22.4 versioned docs --- website/versioned_docs/version-22.4/CLI.md | 347 +++++ .../version-22.4/Configuration.md | 1119 ++++++++++++++++ .../versioned_docs/version-22.4/ExpectAPI.md | 1132 +++++++++++++++++ .../version-22.4/GettingStarted.md | 156 +++ .../version-22.4/JestCommunity.md | 32 + .../version-22.4/JestObjectAPI.md | 568 +++++++++ .../version-22.4/ManualMocks.md | 180 +++ .../version-22.4/MigrationGuide.md | 48 + .../version-22.4/MockFunctionAPI.md | 336 +++++ .../version-22.4/MockFunctions.md | 324 +++++ .../version-22.4/MoreResources.md | 39 + .../versioned_docs/version-22.4/Puppeteer.md | 124 ++ .../version-22.4/TestingFrameworks.md | 38 + .../version-22.4/Troubleshooting.md | 322 +++++ .../version-22.4/TutorialReact.md | 337 +++++ .../version-22.4/TutorialReactNative.md | 273 ++++ .../version-22.4/UsingMatchers.md | 175 +++ .../versioned_docs/version-22.4/Webpack.md | 281 ++++ .../version-22.4-sidebars.json | 39 + website/versions.json | 1 + 20 files changed, 5871 insertions(+) create mode 100644 website/versioned_docs/version-22.4/CLI.md create mode 100644 website/versioned_docs/version-22.4/Configuration.md create mode 100644 website/versioned_docs/version-22.4/ExpectAPI.md create mode 100644 website/versioned_docs/version-22.4/GettingStarted.md create mode 100644 website/versioned_docs/version-22.4/JestCommunity.md create mode 100644 website/versioned_docs/version-22.4/JestObjectAPI.md create mode 100644 website/versioned_docs/version-22.4/ManualMocks.md create mode 100644 website/versioned_docs/version-22.4/MigrationGuide.md create mode 100644 website/versioned_docs/version-22.4/MockFunctionAPI.md create mode 100644 website/versioned_docs/version-22.4/MockFunctions.md create mode 100644 website/versioned_docs/version-22.4/MoreResources.md create mode 100644 website/versioned_docs/version-22.4/Puppeteer.md create mode 100644 website/versioned_docs/version-22.4/TestingFrameworks.md create mode 100644 website/versioned_docs/version-22.4/Troubleshooting.md create mode 100644 website/versioned_docs/version-22.4/TutorialReact.md create mode 100644 website/versioned_docs/version-22.4/TutorialReactNative.md create mode 100644 website/versioned_docs/version-22.4/UsingMatchers.md create mode 100644 website/versioned_docs/version-22.4/Webpack.md create mode 100644 website/versioned_sidebars/version-22.4-sidebars.json diff --git a/website/versioned_docs/version-22.4/CLI.md b/website/versioned_docs/version-22.4/CLI.md new file mode 100644 index 000000000000..5b134d3efeb9 --- /dev/null +++ b/website/versioned_docs/version-22.4/CLI.md @@ -0,0 +1,347 @@ +--- +id: version-22.4-cli +title: Jest CLI Options +original_id: cli +--- + +The `jest` command line runner has a number of useful options. You can run +`jest --help` to view all available options. Many of the options shown below can +also be used together to run tests exactly the way you want. Every one of Jest's +[Configuration](Configuration.md) options can also be specified through the CLI. + +Here is a brief overview: + +## Running from the command line + +Run all tests (default): + +```bash +jest +``` + +Run only the tests that were specified with a pattern or filename: + +```bash +jest my-test #or +jest path/to/my-test.js +``` + +Run tests related to changed files based on hg/git (uncommitted files): + +```bash +jest -o +``` + +Run tests related to `path/to/fileA.js` and `path/to/fileB.js`: + +```bash +jest --findRelatedTests path/to/fileA.js path/to/fileB.js +``` + +Run tests that match this spec name (match against the name in `describe` or +`test`, basically). + +```bash +jest -t name-of-spec +``` + +Run watch mode: + +```bash +jest --watch #runs jest -o by default +jest --watchAll #runs all tests +``` + +Watch mode also enables to specify the name or path to a file to focus on a +specific set of tests. + +## Using with yarn + +If you run Jest via `yarn test`, you can pass the command line arguments +directly as Jest arguments. + +Instead of: + +```bash +jest -u -t="ColorPicker" +``` + +you can use: + +```bash +yarn test -u -t="ColorPicker" +``` + +## Using with npm scripts + +If you run Jest via `npm test`, you can still use the command line arguments by +inserting a `--` between `npm test` and the Jest arguments. + +Instead of: + +```bash +jest -u -t="ColorPicker" +``` + +you can use: + +```bash +npm test -- -u -t="ColorPicker" +``` + +## Options + +_Note: CLI options take precedence over values from the +[Configuration](Configuration.md)._ + + + +--- + +## Reference + +### `jest ` + +When you run `jest` with an argument, that argument is treated as a regular +expression to match against files in your project. It is possible to run test +suites by providing a pattern. Only the files that the pattern matches will be +picked up and executed. Depending on your terminal, you may need to quote this +argument: `jest "my.*(complex)?pattern"`. On Windows, you will need to use `/` +as a path separator or escape `\` as `\\`. + +### `--bail` + +Alias: `-b`. Exit the test suite immediately upon the first failing test suite. + +### `--cache` + +Whether to use the cache. Defaults to true. Disable the cache using +`--no-cache`. _Note: the cache should only be disabled if you are experiencing +caching related problems. On average, disabling the cache makes Jest at least +two times slower._ + +If you want to inspect the cache, use `--showConfig` and look at the +`cacheDirectory` value. If you need to clear the cache, use `--clearCache`. + +### `--changedFilesWithAncestor` + +Runs tests related to the current changes and the changes made in the last +commit. Behaves similarly to `--onlyChanged`. + +### `--changedSince` + +##### available in Jest **22.2.0+** + +Runs tests related the changes since the provided branch. If the current branch +has diverged from the given branch, then only changes made locally will be +tested. Behaves similarly to `--onlyChanged`. + +### `--ci` + +When this option is provided, Jest will assume it is running in a CI +environment. This changes the behavior when a new snapshot is encountered. +Instead of the regular behavior of storing a new snapshot automatically, it will +fail the test and require Jest to be run with `--updateSnapshot`. + +### `--clearCache` + +##### available in Jest **22.0.0+** + +Deletes the Jest cache directory and then exits without running tests. Will +delete `cacheDirectory` if the option is passed, or Jest's default cache +directory. The default cache directory can be found by calling +`jest --showConfig`. _Note: clearing the cache will reduce performance._ + +### `--collectCoverageFrom=` + +An array of glob patterns relative to matching the files that coverage +info needs to be collected from. + +### `--colors` + +Forces test results output highlighting even if stdout is not a TTY. + +### `--config=` + +Alias: `-c`. The path to a Jest config file specifying how to find and execute +tests. If no `rootDir` is set in the config, the current directory is assumed to +be the rootDir for the project. This can also be a JSON-encoded value which Jest +will use as configuration. + +### `--coverage` + +Indicates that test coverage information should be collected and reported in the +output. + +### `--debug` + +Print debugging info about your Jest config. + +### `--env=` + +The test environment used for all tests. This can point to any file or node +module. Examples: `jsdom`, `node` or `path/to/my-environment.js`. + +### `--expand` + +Alias: `-e`. Use this flag to show full diffs and errors instead of a patch. + +### `--findRelatedTests ` + +Find and run the tests that cover a space separated list of source files that +were passed in as arguments. Useful for pre-commit hook integration to run the +minimal amount of tests necessary. + +### `--forceExit` + +Force Jest to exit after all tests have completed running. This is useful when +resources set up by test code cannot be adequately cleaned up. _Note: This +feature is an escape-hatch. If Jest doesn't exit at the end of a test run, it +means external resources are still being held on to or timers are still pending +in your code. It is advised to tear down external resources after each test to +make sure Jest can shut down cleanly._ + +### `--help` + +Show the help information, similar to this page. + +### `--json` + +Prints the test results in JSON. This mode will send all other test output and +user messages to stderr. + +### `--outputFile=` + +Write test results to a file when the `--json` option is also specified. + +### `--lastCommit` + +Run all tests affected by file changes in the last commit made. Behaves +similarly to `--onlyChanged`. + +### `--listTests` + +Lists all tests as JSON that Jest will run given the arguments, and exits. This +can be used together with `--findRelatedTests` to know which tests Jest will +run. + +### `--logHeapUsage` + +Logs the heap usage after every test. Useful to debug memory leaks. Use together +with `--runInBand` and `--expose-gc` in node. + +### `--maxWorkers=` + +Alias: `-w`. Specifies the maximum number of workers the worker-pool will spawn +for running tests. This defaults to the number of the cores available on your +machine. It may be useful to adjust this in resource limited environments like +CIs but the default should be adequate for most use-cases. + +### `--noStackTrace` + +Disables stack trace in test results output. + +### `--notify` + +Activates notifications for test results. Good for when you don't want your +consciousness to be able to focus on anything except JavaScript testing. + +### `--onlyChanged` + +Alias: `-o`. Attempts to identify which tests to run based on which files have +changed in the current repository. Only works if you're running tests in a +git/hg repository at the moment and requires a static dependency graph (ie. no +dynamic requires). + +### `--passWithNoTests` + +Allows the test suite to pass when no files are found. + +### `--projects ... ` + +Run tests from one or more projects. + +### `--runInBand` + +Alias: `-i`. Run all tests serially in the current process, rather than creating +a worker pool of child processes that run tests. This can be useful for +debugging. + +### `--setupTestFrameworkScriptFile=` + +The path to a module that runs some code to configure or set up the testing +framework before each test. Beware that files imported by the setup script will +not be mocked during testing. + +### `--showConfig` + +Print your Jest config and then exits. + +### `--silent` + +Prevent tests from printing messages through the console. + +### `--testNamePattern=` + +Alias: `-t`. Run only tests and test suites with a name that matches the regex. +For example, suppose you want to run only tests related to authorization which +will have names like `"GET /api/posts with auth"`, then you can use +`jest -t=auth`. + +### `--testLocationInResults` + +Adds a `location` field to test results. Useful if you want to report the +location of a test in a reporter. + +Note that `column` is 0-indexed while `line` is not. + +```json +{ + "column": 4, + "line": 5 +} +``` + +### `--testPathPattern=` + +A regexp pattern string that is matched against all tests paths before executing +the test. On Windows, you will need to use `/` as a path separator or escape `\` +as `\\`. + +### `--testRunner=` + +Lets you specify a custom test runner. + +### `--updateSnapshot` + +Alias: `-u`. Use this flag to re-record every snapshot that fails during this +test run. Can be used together with a test suite pattern or with +`--testNamePattern` to re-record snapshots. + +### `--useStderr` + +Divert all output to stderr. + +### `--verbose` + +Display individual test results with the test suite hierarchy. + +### `--version` + +Alias: `-v`. Print the version and exit. + +### `--watch` + +Watch files for changes and rerun tests related to changed files. If you want to +re-run all tests when a file has changed, use the `--watchAll` option instead. + +### `--watchAll` + +Watch files for changes and rerun all tests when something changes. If you want +to re-run only the tests that depend on the changed files, use the `--watch` +option. + +### `--watchman` + +Whether to use watchman for file crawling. Defaults to true. Disable using +`--no-watchman`. diff --git a/website/versioned_docs/version-22.4/Configuration.md b/website/versioned_docs/version-22.4/Configuration.md new file mode 100644 index 000000000000..a7963ee9bd40 --- /dev/null +++ b/website/versioned_docs/version-22.4/Configuration.md @@ -0,0 +1,1119 @@ +--- +id: version-22.4-configuration +title: Configuring Jest +original_id: configuration +--- + +Jest's configuration can be defined in the `package.json` file of your project, +or through a `jest.config.js` file or through the `--config ` +option. If you'd like to use your `package.json` to store Jest's config, the +"jest" key should be used on the top level so Jest will know how to find your +settings: + +```json +{ + "name": "my-project", + "jest": { + "verbose": true + } +} +``` + +Or through JavaScript: + +```js +// jest.config.js +module.exports = { + verbose: true, +}; +``` + +Please keep in mind that the resulting configuration must be JSON-serializable. + +When using the `--config` option, the JSON file must not contain a "jest" key: + +```json +{ + "bail": true, + "verbose": true +} +``` + +## Options + +These options let you control Jest's behavior in your `package.json` file. The +Jest philosophy is to work great by default, but sometimes you just need more +configuration power. + + + +--- + +## Reference + +### `automock` [boolean] + +Default: `false` + +This option tells Jest that all imported modules in your tests should be mocked +automatically. All modules used in your tests will have a replacement +implementation, keeping the API surface. + +Example: + +```js +// utils.js +export default { + authorize: () => { + return 'token'; + }, + isAuthorized: secret => secret === 'wizard', +}; +``` + +```js +//__tests__/automocking.test.js +import utils from '../utils'; + +test('if utils mocked automatically', () => { + // Public methods of `utils` are now mock functions + expect(utils.authorize.mock).toBeTruthy(); + expect(utils.isAuthorized.mock).toBeTruthy(); + + // You can provide them with your own implementation + // or just pass the expected return value + utils.authorize.mockReturnValue('mocked_token'); + utils.isAuthorized.mockReturnValue(true); + + expect(utils.authorize()).toBe('mocked_token'); + expect(utils.isAuthorized('not_wizard')).toBeTruthy(); +}); +``` + +_Note: Core modules, like `fs`, are not mocked by default. They can be mocked +explicitly, like `jest.mock('fs')`._ + +_Note: Automocking has a performance cost most noticeable in large projects. See +[here](troubleshooting.html#tests-are-slow-when-leveraging-automocking) for +details and a workaround._ + +### `browser` [boolean] + +Default: `false` + +Respect Browserify's +[`"browser"` field](https://github.com/substack/browserify-handbook#browser-field) +in `package.json` when resolving modules. Some modules export different versions +based on whether they are operating in Node or a browser. + +### `bail` [boolean] + +Default: `false` + +By default, Jest runs all tests and produces all errors into the console upon +completion. The bail config option can be used here to have Jest stop running +tests after the first failure. + +### `cacheDirectory` [string] + +Default: `"/tmp/"` + +The directory where Jest should store its cached dependency information. + +Jest attempts to scan your dependency tree once (up-front) and cache it in order +to ease some of the filesystem raking that needs to happen while running tests. +This config option lets you customize where Jest stores that cache data on disk. + +### `collectCoverage` [boolean] + +Default: `false` + +Indicates whether the coverage information should be collected while executing +the test. Because this retrofits all executed files with coverage collection +statements, it may significantly slow down your tests. + +### `collectCoverageFrom` [array] + +Default: `undefined` + +An array of [glob patterns](https://github.com/jonschlinkert/micromatch) +indicating a set of files for which coverage information should be collected. If +a file matches the specified glob pattern, coverage information will be +collected for it even if no tests exist for this file and it's never required in +the test suite. + +Example: + +```json +{ + "collectCoverageFrom": [ + "**/*.{js,jsx}", + "!**/node_modules/**", + "!**/vendor/**" + ] +} +``` + +This will collect coverage information for all the files inside the project's +`rootDir`, except the ones that match `**/node_modules/**` or `**/vendor/**`. + +_Note: This option requires `collectCoverage` to be set to true or Jest to be +invoked with `--coverage`._ + +### `coverageDirectory` [string] + +Default: `undefined` + +The directory where Jest should output its coverage files. + +### `coveragePathIgnorePatterns` [array] + +Default: `["/node_modules/"]` + +An array of regexp pattern strings that are matched against all file paths +before executing the test. If the file path matches any of the patterns, +coverage information will be skipped. + +These pattern strings match against the full path. Use the `` string +token to include the path to your project's root directory to prevent it from +accidentally ignoring all of your files in different environments that may have +different root directories. Example: +`["/build/", "/node_modules/"]`. + +### `coverageReporters` [array] + +Default: `["json", "lcov", "text"]` + +A list of reporter names that Jest uses when writing coverage reports. Any +[istanbul reporter](https://github.com/gotwarlost/istanbul/tree/master/lib/report) +can be used. + +_Note: Setting this option overwrites the default values. Add `"text"` or +`"text-summary"` to see a coverage summary in the console output._ + +### `coverageThreshold` [object] + +Default: `undefined` + +This will be used to configure minimum threshold enforcement for coverage +results. Thresholds can be specified as `global`, as a +[glob](https://github.com/isaacs/node-glob#glob-primer), and as a directory or +file path. If thresholds aren't met, jest will fail. Thresholds specified as a +positive number are taken to be the minimum percentage required. Thresholds +specified as a negative number represent the maximum number of uncovered +entities allowed. + +For example, with the following configuration jest will fail if there is less +than 80% branch, line, and function coverage, or if there are more than 10 +uncovered statements: + +```json +{ + ... + "jest": { + "coverageThreshold": { + "global": { + "branches": 80, + "functions": 80, + "lines": 80, + "statements": -10 + } + } + } +} +``` + +If globs or paths are specified alongside `global`, coverage data for matching +paths will be subtracted from overall coverage and thresholds will be applied +independently. Thresholds for globs are applied to all files matching the glob. +If the file specified by path is not found, error is returned. + +For example, with the following configuration: + +```json +{ + ... + "jest": { + "coverageThreshold": { + "global": { + "branches": 50, + "functions": 50, + "lines": 50, + "statements": 50 + }, + "./src/components/": { + "branches": 40, + "statements": 40 + }, + "./src/reducers/**/*.js": { + "statements": 90, + }, + "./src/api/very-important-module.js": { + "branches": 100, + "functions": 100, + "lines": 100, + "statements": 100 + } + } + } +} +``` + +Jest will fail if: + +* The `./src/components` directory has less than 40% branch or statement + coverage. +* One of the files matching the `./src/reducers/**/*.js` glob has less than 90% + statement coverage. +* The `./src/api/very-important-module.js` file has less than 100% coverage. +* Every remaining file combined has less than 50% coverage (`global`). + +### `forceCoverageMatch` [array] + +Default: `['']` + +Test files are normally ignored from collecting code coverage. With this option, +you can overwrite this behavior and include otherwise ignored files in code +coverage. + +For example, if you have tests in source files named with `.t.js` extension as +following: + +```javascript +// sum.t.js + +export function sum(a, b) { + return a + b; +} + +if (process.env.NODE_ENV === 'test') { + test('sum', () => { + expect(sum(1, 2)).toBe(3); + }); +} +``` + +You can collect coverage from those files with setting `forceCoverageMatch`. + +```json +{ + ... + "jest": { + "forceCoverageMatch": ["**/*.t.js"] + } +} +``` + +### `globals` [object] + +Default: `{}` + +A set of global variables that need to be available in all test environments. + +For example, the following would create a global `__DEV__` variable set to +`true` in all test environments: + +```json +{ + ... + "jest": { + "globals": { + "__DEV__": true + } + } +} +``` + +Note that, if you specify a global reference value (like an object or array) +here, and some code mutates that value in the midst of running a test, that +mutation will _not_ be persisted across test runs for other test files. In +addition the `globals` object must be json-serializable, so it can't be used to +specify global functions. For that you should use `setupFiles`. + +### `globalSetup` [string] + +Default: `undefined` + +This option allows the use of a custom global setup module which exports an +async function that is triggered once before all test suites. + +### `globalTeardown` [string] + +Default: `undefined` + +This option allows the use of a custom global teardown module which exports an +async function that is triggered once after all test suites. + +### `moduleFileExtensions` [array] + +Default: `["js", "json", "jsx", "node"]` + +An array of file extensions your modules use. If you require modules without +specifying a file extension, these are the extensions Jest will look for. + +If you are using TypeScript this should be `["js", "jsx", "json", "ts", "tsx"]`, +check [ts-jest's documentation](https://github.com/kulshekhar/ts-jest). + +### `moduleDirectories` [array] + +Default: `["node_modules"]` + +An array of directory names to be searched recursively up from the requiring +module's location. Setting this option will _override_ the default, if you wish +to still search `node_modules` for packages include it along with any other +options: `["node_modules", "bower_components"]` + +### `moduleNameMapper` [object] + +Default: `null` + +A map from regular expressions to module names that allow to stub out resources, +like images or styles with a single module. + +Modules that are mapped to an alias are unmocked by default, regardless of +whether automocking is enabled or not. + +Use `` string token to refer to [`rootDir`](#rootdir-string) value if +you want to use file paths. + +Additionally, you can substitute captured regex groups using numbered +backreferences. + +Example: + +```json +{ + "moduleNameMapper": { + "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub", + "^[./a-zA-Z0-9$_-]+\\.png$": "/RelativeImageStub.js", + "module_name_(.*)": "/substituted_module_$1.js" + } +} +``` + +The order in which the mappings are defined matters. Patterns are checked one by +one until one fits. The most specific rule should be listed first. + +_Note: If you provide module name without boundaries `^$` it may cause hard to +spot errors. E.g. `relay` will replace all modules which contain `relay` as a +substring in its name: `relay`, `react-relay` and `graphql-relay` will all be +pointed to your stub._ + +### `modulePathIgnorePatterns` [array] + +Default: `[]` + +An array of regexp pattern strings that are matched against all module paths +before those paths are to be considered 'visible' to the module loader. If a +given module's path matches any of the patterns, it will not be `require()`-able +in the test environment. + +These pattern strings match against the full path. Use the `` string +token to include the path to your project's root directory to prevent it from +accidentally ignoring all of your files in different environments that may have +different root directories. Example: `["/build/"]`. + +### `modulePaths` [array] + +Default: `[]` + +An alternative API to setting the `NODE_PATH` env variable, `modulePaths` is an +array of absolute paths to additional locations to search when resolving +modules. Use the `` string token to include the path to your project's +root directory. Example: `["/app/"]`. + +### `notify` [boolean] + +Default: `false` + +Activates notifications for test results. + +### `notifyMode` [string] + +Default: `always` + +Specifies notification mode. Requires `notify: true`. + +#### Modes + +* `always`: always send a notification. +* `failure`: send a notification when tests fail. +* `success`: send a notification when tests pass. +* `change`: send a notification when the status changed. +* `success-change`: send a notification when tests pass or once when it fails. +* `failure-success`: send a notification when tests fails or once when it + passes. + +### `preset` [string] + +Default: `undefined` + +A preset that is used as a base for Jest's configuration. A preset should point +to an npm module that exports a `jest-preset.json` module on its top level. + +### `projects` [array] + +Default: `undefined` + +When the `projects` configuration is provided with an array of paths or glob +patterns, Jest will run tests in all of the specified projects at the same time. +This is great for monorepos or when working on multiple projects at the same +time. + +```json +{ + "projects": ["", "/examples/*"] +} +``` + +This example configuration will run Jest in the root directory as well as in +every folder in the examples directory. You can have an unlimited amount of +projects running in the same Jest instance. + +The projects feature can also be used to run multiple configurations or multiple +[runners](#runner-string). For this purpose you can pass an array of +configuration objects. For example, to run both tests and ESLint (via +[jest-runner-eslint](https://github.com/jest-community/jest-runner-eslint)) in +the same invocation of Jest: + +```json +{ + "projects": [ + { + "displayName": "test" + }, + { + "displayName": "lint", + "runner": "jest-runner-eslint", + "testMatch": ["/**/*.js"] + } + ] +} +``` + +_Note: When using multi project runner, it's recommended to add a `displayName` +for each project. This will show the `displayName` of a project next to its +tests._ + +### `clearMocks` [boolean] + +Default: `false` + +Automatically clear mock calls and instances between every test. Equivalent to +calling `jest.clearAllMocks()` between each test. This does not remove any mock +implementation that may have been provided. + +### `reporters` [array] + +Default: `undefined` + +##### available in Jest **20.0.0+** + +Use this configuration option to add custom reporters to Jest. A custom reporter +is a class that implements `onRunStart`, `onTestStart`, `onTestResult`, +`onRunComplete` methods that will be called when any of those events occurs. + +If custom reporters are specified, the default Jest reporters will be +overridden. To keep default reporters, `default` can be passed as a module name. + +This will override default reporters: + +```json +{ + "reporters": ["/my-custom-reporter.js"] +} +``` + +This will use custom reporter in addition to default reporters that Jest +provides: + +```json +{ + "reporters": ["default", "/my-custom-reporter.js"] +} +``` + +Additionally, custom reporters can be configured by passing an `options` object +as a second argument: + +```json +{ + "reporters": [ + "default", + ["/my-custom-reporter.js", {"banana": "yes", "pineapple": "no"}] + ] +} +``` + +Custom reporter modules must define a class that takes a `GlobalConfig` and +reporter options as constructor arguments: + +Example reporter: + +```js +// my-custom-reporter.js +class MyCustomReporter { + constructor(globalConfig, options) { + this._globalConfig = globalConfig; + this._options = options; + } + + onRunComplete(contexts, results) { + console.log('Custom reporter output:'); + console.log('GlobalConfig: ', this._globalConfig); + console.log('Options: ', this._options); + } +} + +module.exports = MyCustomReporter; +``` + +Custom reporters can also force Jest to exit with non-0 code by returning an +Error from `getLastError()` methods + +```js +class MyCustomReporter { + // ... + getLastError() { + if (this._shouldFail) { + return new Error('my-custom-reporter.js reported an error'); + } + } +} +``` + +For the full list of methods and argument types see `Reporter` type in +[types/TestRunner.js](https://github.com/facebook/jest/blob/master/types/TestRunner.js) + +### `resetMocks` [boolean] + +Default: `false` + +Automatically reset mock state between every test. Equivalent to calling +`jest.resetAllMocks()` between each test. This will lead to any mocks having +their fake implementations removed but does not restore their initial +implementation. + +### `resetModules` [boolean] + +Default: `false` + +If enabled, the module registry for every test file will be reset before running +each individual test. This is useful to isolate modules for every test so that +local module state doesn't conflict between tests. This can be done +programmatically using [`jest.resetModules()`](#jest-resetmodules). + +### `resolver` [string] + +Default: `undefined` + +##### available in Jest **20.0.0+** + +This option allows the use of a custom resolver. This resolver must be a node +module that exports a function expecting a string as the first argument for the +path to resolve and an object with the following structure as the second +argument: + +```json +{ + "basedir": string, + "browser": bool, + "extensions": [string], + "moduleDirectory": [string], + "paths": [string], + "rootDir": [string] +} +``` + +The function should either return a path to the module that should be resolved +or throw an error if the module can't be found. + +### `restoreMocks` [boolean] + +Default: `false` + +Automatically restore mock state between every test. Equivalent to calling +`jest.restoreAllMocks()` between each test. This will lead to any mocks having +their fake implementations removed and restores their initial implementation. + +### `rootDir` [string] + +Default: The root of the directory containing your jest's [config file](#) _or_ +the `package.json` _or_ the [`pwd`](http://en.wikipedia.org/wiki/Pwd) if no +`package.json` is found + +The root directory that Jest should scan for tests and modules within. If you +put your Jest config inside your `package.json` and want the root directory to +be the root of your repo, the value for this config param will default to the +directory of the `package.json`. + +Oftentimes, you'll want to set this to `'src'` or `'lib'`, corresponding to +where in your repository the code is stored. + +_Note that using `''` as a string token in any other path-based config +settings will refer back to this value. So, for example, if you want your +[`setupFiles`](#setupfiles-array) config entry to point at the `env-setup.js` +file at the root of your project, you could set its value to +`["/env-setup.js"]`._ + +### `roots` [array] + +Default: `[""]` + +A list of paths to directories that Jest should use to search for files in. + +There are times where you only want Jest to search in a single sub-directory +(such as cases where you have a `src/` directory in your repo), but prevent it +from accessing the rest of the repo. + +_Note: While `rootDir` is mostly used as a token to be re-used in other +configuration options, `roots` is used by the internals of Jest to locate **test +files and source files**. This applies also when searching for manual mocks for +modules from `node_modules` (`__mocks__` will need to live in one of the +`roots`)._ + +_Note: By default, `roots` has a single entry `` but there are cases +where you may want to have multiple roots within one project, for example +`roots: ["/src/", "/tests/"]`._ + +### `runner` [string] + +##### available in Jest **21.0.0+** + +Default: `"jest-runner"` + +This option allows you to use a custom runner instead of Jest's default test +runner. Examples of runners include: + +* [`jest-runner-eslint`](https://github.com/jest-community/jest-runner-eslint) +* [`jest-runner-mocha`](https://github.com/rogeliog/jest-runner-mocha) +* [`jest-runner-tsc`](https://github.com/azz/jest-runner-tsc) +* [`jest-runner-prettier`](https://github.com/keplersj/jest-runner-prettier) + +To write a test-runner, export a class with which accepts `globalConfig` in the +constructor, and has a `runTests` method with the signature: + +```ts +async runTests( + tests: Array, + watcher: TestWatcher, + onStart: OnTestStart, + onResult: OnTestSuccess, + onFailure: OnTestFailure, + options: TestRunnerOptions, +): Promise +``` + +### `setupFiles` [array] + +Default: `[]` + +The paths to modules that run some code to configure or set up the testing +environment before each test. Since every test runs in its own environment, +these scripts will be executed in the testing environment immediately before +executing the test code itself. + +It's worth noting that this code will execute _before_ +[`setupTestFrameworkScriptFile`](#setuptestframeworkscriptfile-string). + +### `setupTestFrameworkScriptFile` [string] + +Default: `undefined` + +The path to a module that runs some code to configure or set up the testing +framework before each test. Since [`setupFiles`](#setupfiles-array) executes +before the test framework is installed in the environment, this script file +presents you the opportunity of running some code immediately after the test +framework has been installed in the environment. + +For example, Jest ships with several plug-ins to `jasmine` that work by +monkey-patching the jasmine API. If you wanted to add even more jasmine plugins +to the mix (or if you wanted some custom, project-wide matchers for example), +you could do so in this module. + +### `snapshotSerializers` [array] + +Default: `[]` + +A list of paths to snapshot serializer modules Jest should use for snapshot +testing. + +Jest has default serializers for built-in JavaScript types, HTML elements (Jest +20.0.0+), ImmutableJS (Jest 20.0.0+) and for React elements. See +[snapshot test tutorial](TutorialReactNative.md#snapshot-test) for more +information. + +Example serializer module: + +```js +// my-serializer-module +module.exports = { + print(val, serialize, indent) { + return 'Pretty foo: ' + serialize(val.foo); + }, + + test(val) { + return val && val.hasOwnProperty('foo'); + }, +}; +``` + +`serialize` is a function that serializes a value using existing plugins. + +To use `my-serializer-module` as a serializer, configuration would be as +follows: + +```json +{ + ... + "jest": { + "snapshotSerializers": ["my-serializer-module"] + } +} +``` + +Finally tests would look as follows: + +```js +test(() => { + const bar = { + foo: { + x: 1, + y: 2, + }, + }; + + expect(bar).toMatchSnapshot(); +}); +``` + +Rendered snapshot: + +```json +Pretty foo: Object { + "x": 1, + "y": 2, +} +``` + +To make a dependency explicit instead of implicit, you can call +[`expect.addSnapshotSerializer`](ExpectAPI.md#expectaddsnapshotserializerserializer) +to add a module for an individual test file instead of adding its path to +`snapshotSerializers` in Jest configuration. + +### `testEnvironment` [string] + +Default: `"jsdom"` + +The test environment that will be used for testing. The default environment in +Jest is a browser-like environment through +[jsdom](https://github.com/tmpvar/jsdom). If you are building a node service, +you can use the `node` option to use a node-like environment instead. + +If some tests require another environment, you can add a `@jest-environment` +docblock. + +##### available in Jest **20.0.0+** + +```js +/** + * @jest-environment jsdom + */ + +test('use jsdom in this test file', () => { + const element = document.createElement('div'); + expect(element).not.toBeNull(); +}); +``` + +You can create your own module that will be used for setting up the test +environment. The module must export a class with `setup`, `teardown` and +`runScript` methods. You can also pass variables from this module to your test +suites by assigning them to `this.global` object – this will make them +available in your test suites as global variables. + +##### available in Jest **22.0.0+** + +_Note: TestEnvironment is sandboxed. Each test suite will trigger setup/teardown +in their own TestEnvironment._ + +Example: + +```js +// my-custom-environment +const NodeEnvironment = require('jest-environment-node'); + +class CustomEnvironment extends NodeEnvironment { + constructor(config) { + super(config); + } + + async setup() { + await super.setup(); + await someSetupTasks(); + this.global.someGlobalObject = createGlobalObject(); + } + + async teardown() { + this.global.someGlobalObject = destroyGlobalObject(); + await someTeardownTasks(); + await super.teardown(); + } + + runScript(script) { + return super.runScript(script); + } +} +``` + +```js +// my-test-suite +let someGlobalObject; + +beforeAll(() => { + someGlobalObject = global.someGlobalObject; +}); +``` + +### `testEnvironmentOptions` [Object] + +##### available in Jest **22.0.0+** + +Default: `{}` + +Test environment options that will be passed to the `testEnvironment`. The +relevant options depend on the environment. For example you can override options +given to [jsdom](https://github.com/tmpvar/jsdom) such as +`{userAgent: "Agent/007"}`. + +### `testMatch` [array] + +##### available in Jest **19.0.0+** + +(default: `[ '**/__tests__/**/*.js?(x)', '**/?(*.)(spec|test).js?(x)' ]`) + +The glob patterns Jest uses to detect test files. By default it looks for `.js` +and `.jsx` files inside of `__tests__` folders, as well as any files with a +suffix of `.test` or `.spec` (e.g. `Component.test.js` or `Component.spec.js`). +It will also find files called `test.js` or `spec.js`. + +See the [micromatch](https://github.com/jonschlinkert/micromatch) package for +details of the patterns you can specify. + +See also [`testRegex` [string]](#testregex-string), but note that you cannot +specify both options. + +### `testPathIgnorePatterns` [array] + +Default: `["/node_modules/"]` + +An array of regexp pattern strings that are matched against all test paths +before executing the test. If the test path matches any of the patterns, it will +be skipped. + +These pattern strings match against the full path. Use the `` string +token to include the path to your project's root directory to prevent it from +accidentally ignoring all of your files in different environments that may have +different root directories. Example: +`["/build/", "/node_modules/"]`. + +### `testRegex` [string] + +Default: `(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$` + +The pattern Jest uses to detect test files. By default it looks for `.js` and +`.jsx` files inside of `__tests__` folders, as well as any files with a suffix +of `.test` or `.spec` (e.g. `Component.test.js` or `Component.spec.js`). It will +also find files called `test.js` or `spec.js`. See also +[`testMatch` [array]](#testmatch-array-string), but note that you cannot +specify both options. + +The following is a visualization of the default regex: + +```bash +├── __tests__ +│ └── component.spec.js # test +│ └── anything # test +├── package.json # not test +├── foo.test.js # test +├── bar.spec.jsx # test +└── component.js # not test +``` + +### `testResultsProcessor` [string] + +Default: `undefined` + +This option allows the use of a custom results processor. This processor must be +a node module that exports a function expecting an object with the following +structure as the first argument and return it: + +```json +{ + "success": bool, + "startTime": epoch, + "numTotalTestSuites": number, + "numPassedTestSuites": number, + "numFailedTestSuites": number, + "numRuntimeErrorTestSuites": number, + "numTotalTests": number, + "numPassedTests": number, + "numFailedTests": number, + "numPendingTests": number, + "testResults": [{ + "numFailingTests": number, + "numPassingTests": number, + "numPendingTests": number, + "testResults": [{ + "title": string (message in it block), + "status": "failed" | "pending" | "passed", + "ancestorTitles": [string (message in describe blocks)], + "failureMessages": [string], + "numPassingAsserts": number, + "location": { + "column": number, + "line": number + } + }, + ... + ], + "perfStats": { + "start": epoch, + "end": epoch + }, + "testFilePath": absolute path to test file, + "coverage": {} + }, + ... + ] +} +``` + +### `testRunner` [string] + +Default: `jasmine2` + +This option allows use of a custom test runner. The default is jasmine2. A +custom test runner can be provided by specifying a path to a test runner +implementation. + +The test runner module must export a function with the following signature: + +```ts +function testRunner( + config: Config, + environment: Environment, + runtime: Runtime, + testPath: string, +): Promise; +``` + +An example of such function can be found in our default +[jasmine2 test runner package](https://github.com/facebook/jest/blob/master/packages/jest-jasmine2/src/index.js). + +### `testURL` [string] + +Default: `about:blank` + +This option sets the URL for the jsdom environment. It is reflected in +properties such as `location.href`. + +### `timers` [string] + +Default: `real` + +Setting this value to `fake` allows the use of fake timers for functions such as +`setTimeout`. Fake timers are useful when a piece of code sets a long timeout +that we don't want to wait for in a test. + +### `transform` [object] + +Default: `undefined` + +A map from regular expressions to paths to transformers. A transformer is a +module that provides a synchronous function for transforming source files. For +example, if you wanted to be able to use a new language feature in your modules +or tests that isn't yet supported by node, you might plug in one of many +compilers that compile a future version of JavaScript to a current one. Example: +see the +[examples/typescript](https://github.com/facebook/jest/blob/master/examples/typescript/package.json#L16) +example or the [webpack tutorial](Webpack.md). + +Examples of such compilers include [Babel](https://babeljs.io/), +[TypeScript](http://www.typescriptlang.org/) and +[async-to-gen](http://github.com/leebyron/async-to-gen#jest). + +_Note: a transformer is only ran once per file unless the file has changed. +During development of a transformer it can be useful to run Jest with +`--no-cache` to frequently +[delete Jest's cache](Troubleshooting.md#caching-issues)._ + +_Note: if you are using the `babel-jest` transformer and want to use an +additional code preprocessor, keep in mind that when "transform" is overwritten +in any way the `babel-jest` is not loaded automatically anymore. If you want to +use it to compile JavaScript code it has to be explicitly defined. See +[babel-jest plugin](https://github.com/facebook/jest/tree/master/packages/babel-jest#setup)_ + +### `transformIgnorePatterns` [array] + +Default: `["/node_modules/"]` + +An array of regexp pattern strings that are matched against all source file +paths before transformation. If the test path matches any of the patterns, it +will not be transformed. + +These pattern strings match against the full path. Use the `` string +token to include the path to your project's root directory to prevent it from +accidentally ignoring all of your files in different environments that may have +different root directories. + +Example: `["/bower_components/", "/node_modules/"]`. + +Sometimes it happens (especially in React Native or TypeScript projects) that +3rd party modules are published as untranspiled. Since all files inside +`node_modules` are not transformed by default, Jest will not understand the code +in these modules, resulting in syntax errors. To overcome this, you may use +`transformIgnorePatterns` to whitelist such modules. You'll find a good example +of this use case in +[React Native Guide](http://facebook.github.io/jest/docs/en/tutorial-react-native.html#transformignorepatterns-customization). + +### `unmockedModulePathPatterns` [array] + +Default: `[]` + +An array of regexp pattern strings that are matched against all modules before +the module loader will automatically return a mock for them. If a module's path +matches any of the patterns in this list, it will not be automatically mocked by +the module loader. + +This is useful for some commonly used 'utility' modules that are almost always +used as implementation details almost all the time (like underscore/lo-dash, +etc). It's generally a best practice to keep this list as small as possible and +always use explicit `jest.mock()`/`jest.unmock()` calls in individual tests. +Explicit per-test setup is far easier for other readers of the test to reason +about the environment the test will run in. + +It is possible to override this setting in individual tests by explicitly +calling `jest.mock()` at the top of the test file. + +### `verbose` [boolean] + +Default: `false` + +Indicates whether each individual test should be reported during the run. All +errors will also still be shown on the bottom after execution. + +### `watchPathIgnorePatterns` [array] + +Default: `[]` + +##### available in Jest **21.0.0+** + +An array of RegExp patterns that are matched against all source file paths +before re-running tests in watch mode. If the file path matches any of the +patterns, when it is updated, it will not trigger a re-run of tests. + +These patterns match against the full path. Use the `` string token to +include the path to your project's root directory to prevent it from +accidentally ignoring all of your files in different environments that may have +different root directories. Example: `["/node_modules/"]`. diff --git a/website/versioned_docs/version-22.4/ExpectAPI.md b/website/versioned_docs/version-22.4/ExpectAPI.md new file mode 100644 index 000000000000..47f6c675fe40 --- /dev/null +++ b/website/versioned_docs/version-22.4/ExpectAPI.md @@ -0,0 +1,1132 @@ +--- +id: version-22.4-expect +title: Expect +original_id: expect +--- + +When you're writing tests, you often need to check that values meet certain +conditions. `expect` gives you access to a number of "matchers" that let you +validate different things. + +## Methods + + + +--- + +## Reference + +### `expect(value)` + +The `expect` function is used every time you want to test a value. You will +rarely call `expect` by itself. Instead, you will use `expect` along with a +"matcher" function to assert something about a value. + +It's easier to understand this with an example. Let's say you have a method +`bestLaCroixFlavor()` which is supposed to return the string `'grapefruit'`. +Here's how you would test that: + +```js +test('the best flavor is grapefruit', () => { + expect(bestLaCroixFlavor()).toBe('grapefruit'); +}); +``` + +In this case, `toBe` is the matcher function. There are a lot of different +matcher functions, documented below, to help you test different things. + +The argument to `expect` should be the value that your code produces, and any +argument to the matcher should be the correct value. If you mix them up, your +tests will still work, but the error messages on failing tests will look +strange. + +### `expect.extend(matchers)` + +You can use `expect.extend` to add your own matchers to Jest. For example, let's +say that you're testing a number theory library and you're frequently asserting +that numbers are divisible by other numbers. You could abstract that into a +`toBeDivisibleBy` matcher: + +```js +expect.extend({ + toBeDivisibleBy(received, argument) { + const pass = received % argument == 0; + if (pass) { + return { + message: () => + `expected ${received} not to be divisible by ${argument}`, + pass: true, + }; + } else { + return { + message: () => `expected ${received} to be divisible by ${argument}`, + pass: false, + }; + } + }, +}); + +test('even and odd numbers', () => { + expect(100).toBeDivisibleBy(2); + expect(101).not.toBeDivisibleBy(2); +}); +``` + +Matchers should return an object with two keys. `pass` indicates whether there +was a match or not, and `message` provides a function with no arguments that +returns an error message in case of failure. Thus, when `pass` is false, +`message` should return the error message for when `expect(x).yourMatcher()` +fails. And when `pass` is true, `message` should return the error message for +when `expect(x).not.yourMatcher()` fails. + +These helper functions can be found on `this` inside a custom matcher: + +#### `this.isNot` + +A boolean to let you know this matcher was called with the negated `.not` +modifier allowing you to flip your assertion. + +#### `this.equals(a, b)` + +This is a deep-equality function that will return `true` if two objects have the +same values (recursively). + +#### `this.utils` + +There are a number of helpful tools exposed on `this.utils` primarily consisting +of the exports from +[`jest-matcher-utils`](https://github.com/facebook/jest/tree/master/packages/jest-matcher-utils). + +The most useful ones are `matcherHint`, `printExpected` and `printReceived` to +format the error messages nicely. For example, take a look at the implementation +for the `toBe` matcher: + +```js +const diff = require('jest-diff'); +expect.extend({ + toBe(received, expected) { + const pass = Object.is(received, expected); + + const message = pass + ? () => + this.utils.matcherHint('.not.toBe') + + '\n\n' + + `Expected value to not be (using Object.is):\n` + + ` ${this.utils.printExpected(expected)}\n` + + `Received:\n` + + ` ${this.utils.printReceived(received)}` + : () => { + const diffString = diff(expected, received, { + expand: this.expand, + }); + return ( + this.utils.matcherHint('.toBe') + + '\n\n' + + `Expected value to be (using Object.is):\n` + + ` ${this.utils.printExpected(expected)}\n` + + `Received:\n` + + ` ${this.utils.printReceived(received)}` + + (diffString ? `\n\nDifference:\n\n${diffString}` : '') + ); + }; + + return {actual: received, message, pass}; + }, +}); +``` + +This will print something like this: + +```bash + expect(received).toBe(expected) + + Expected value to be (using Object.is): + "banana" + Received: + "apple" +``` + +When an assertion fails, the error message should give as much signal as +necessary to the user so they can resolve their issue quickly. You should craft +a precise failure message to make sure users of your custom assertions have a +good developer experience. + +### `expect.anything()` + +`expect.anything()` matches anything but `null` or `undefined`. You can use it +inside `toEqual` or `toBeCalledWith` instead of a literal value. For example, if +you want to check that a mock function is called with a non-null argument: + +```js +test('map calls its argument with a non-null argument', () => { + const mock = jest.fn(); + [1].map(x => mock(x)); + expect(mock).toBeCalledWith(expect.anything()); +}); +``` + +### `expect.any(constructor)` + +`expect.any(constructor)` matches anything that was created with the given +constructor. You can use it inside `toEqual` or `toBeCalledWith` instead of a +literal value. For example, if you want to check that a mock function is called +with a number: + +```js +function randocall(fn) { + return fn(Math.floor(Math.random() * 6 + 1)); +} + +test('randocall calls its callback with a number', () => { + const mock = jest.fn(); + randocall(mock); + expect(mock).toBeCalledWith(expect.any(Number)); +}); +``` + +### `expect.arrayContaining(array)` + +`expect.arrayContaining(array)` matches a received array which contains all of +the elements in the expected array. That is, the expected array is a **subset** +of the received array. Therefore, it matches a received array which contains +elements that are **not** in the expected array. + +You can use it instead of a literal value: + +* in `toEqual` or `toBeCalledWith` +* to match a property in `objectContaining` or `toMatchObject` + +```js +describe('arrayContaining', () => { + const expected = ['Alice', 'Bob']; + it('matches even if received contains additional elements', () => { + expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected)); + }); + it('does not match if received does not contain expected elements', () => { + expect(['Bob', 'Eve']).not.toEqual(expect.arrayContaining(expected)); + }); +}); +``` + +```js +describe('Beware of a misunderstanding! A sequence of dice rolls', () => { + const expected = [1, 2, 3, 4, 5, 6]; + it('matches even with an unexpected number 7', () => { + expect([4, 1, 6, 7, 3, 5, 2, 5, 4, 6]).toEqual( + expect.arrayContaining(expected), + ); + }); + it('does not match without an expected number 2', () => { + expect([4, 1, 6, 7, 3, 5, 7, 5, 4, 6]).not.toEqual( + expect.arrayContaining(expected), + ); + }); +}); +``` + +### `expect.assertions(number)` + +`expect.assertions(number)` verifies that a certain number of assertions are +called during a test. This is often useful when testing asynchronous code, in +order to make sure that assertions in a callback actually got called. + +For example, let's say that we have a function `doAsync` that receives two +callbacks `callback1` and `callback2`, it will asynchronously call both of them +in an unknown order. We can test this with: + +```js +test('doAsync calls both callbacks', () => { + expect.assertions(2); + function callback1(data) { + expect(data).toBeTruthy(); + } + function callback2(data) { + expect(data).toBeTruthy(); + } + + doAsync(callback1, callback2); +}); +``` + +The `expect.assertions(2)` call ensures that both callbacks actually get called. + +### `expect.hasAssertions()` + +`expect.hasAssertions()` verifies that at least one assertion is called during a +test. This is often useful when testing asynchronous code, in order to make sure +that assertions in a callback actually got called. + +For example, let's say that we have a few functions that all deal with state. +`prepareState` calls a callback with a state object, `validateState` runs on +that state object, and `waitOnState` returns a promise that waits until all +`prepareState` callbacks complete. We can test this with: + +```js +test('prepareState prepares a valid state', () => { + expect.hasAssertions(); + prepareState(state => { + expect(validateState(state)).toBeTruthy(); + }); + return waitOnState(); +}); +``` + +The `expect.hasAssertions()` call ensures that the `prepareState` callback +actually gets called. + +### `expect.not.arrayContaining(array)` + +`expect.not.arrayContaining(array)` matches a received array which contains none +of the elements in the expected array. That is, the expected array **is not a +subset** of the received array. + +It is the inverse of `expect.arrayContaining`. + +```js +describe('not.arrayContaining', () => { + const expected = ['Samantha']; + + it('matches if the actual array does not contain the expected elements', () => { + expect(['Alice', 'Bob', 'Eve']).toEqual( + expect.not.arrayContaining(expected), + ); + }); +}); +``` + +### `expect.not.objectContaining(object)` + +`expect.not.objectContaining(object)` matches any received object that does not +recursively match the expected properties. That is, the expected object **is not +a subset** of the received object. Therefore, it matches a received object which +contains properties that are **not** in the expected object. + +It is the inverse of `expect.objectContaining`. + +```js +describe('not.objectContaining', () => { + const expected = {foo: 'bar'}; + + it('matches if the actual object does not contain expected key: value pairs', () => { + expect({bar: 'baz'}).toEqual(expect.not.objectContaining(expected)); + }); +}); +``` + +### `expect.not.stringContaining(string)` + +`expect.not.stringContaining(string)` matches any received string that does not +contain the exact expected string. + +It is the inverse of `expect.stringContaining`. + +```js +describe('not.stringContaining', () => { + const expected = 'Hello world!'; + + it('matches if the actual string does not contain the expected substring', () => { + expect('How are you?').toEqual(expect.not.stringContaining(expected)); + }); +}); +``` + +### `expect.not.stringMatching(regexp)` + +`expect.not.stringMatching(regexp)` matches any received string that does not +match the expected regexp. + +It is the inverse of `expect.stringMatching`. + +```js +describe('not.stringMatching', () => { + const expected = /Hello world!/; + + it('matches if the actual string does not match the expected regex', () => { + expect('How are you?').toEqual(expect.not.stringMatching(expected)); + }); +}); +``` + +### `expect.objectContaining(object)` + +`expect.objectContaining(object)` matches any received object that recursively +matches the expected properties. That is, the expected object is a **subset** of +the received object. Therefore, it matches a received object which contains +properties that are **not** in the expected object. + +Instead of literal property values in the expected object, you can use matchers, +`expect.anything()`, and so on. + +For example, let's say that we expect an `onPress` function to be called with an +`Event` object, and all we need to verify is that the event has `event.x` and +`event.y` properties. We can do that with: + +```js +test('onPress gets called with the right thing', () => { + const onPress = jest.fn(); + simulatePresses(onPress); + expect(onPress).toBeCalledWith( + expect.objectContaining({ + x: expect.any(Number), + y: expect.any(Number), + }), + ); +}); +``` + +### `expect.stringContaining(string)` + +`expect.stringContaining(string)` matches any received string that contains the +exact expected string. + +### `expect.stringMatching(regexp)` + +`expect.stringMatching(regexp)` matches any received string that matches the +expected regexp. + +You can use it instead of a literal value: + +* in `toEqual` or `toBeCalledWith` +* to match an element in `arrayContaining` +* to match a property in `objectContaining` or `toMatchObject` + +This example also shows how you can nest multiple asymmetric matchers, with +`expect.stringMatching` inside the `expect.arrayContaining`. + +```js +describe('stringMatching in arrayContaining', () => { + const expected = [ + expect.stringMatching(/^Alic/), + expect.stringMatching(/^[BR]ob/), + ]; + it('matches even if received contains additional elements', () => { + expect(['Alicia', 'Roberto', 'Evelina']).toEqual( + expect.arrayContaining(expected), + ); + }); + it('does not match if received does not contain expected elements', () => { + expect(['Roberto', 'Evelina']).not.toEqual( + expect.arrayContaining(expected), + ); + }); +}); +``` + +### `expect.addSnapshotSerializer(serializer)` + +You can call `expect.addSnapshotSerializer` to add a module that formats +application-specific data structures. + +For an individual test file, an added module precedes any modules from +`snapshotSerializers` configuration, which precede the default snapshot +serializers for built-in JavaScript types and for React elements. The last +module added is the first module tested. + +```js +import serializer from 'my-serializer-module'; +expect.addSnapshotSerializer(serializer); + +// affects expect(value).toMatchSnapshot() assertions in the test file +``` + +If you add a snapshot serializer in individual test files instead of to adding +it to `snapshotSerializers` configuration: + +* You make the dependency explicit instead of implicit. +* You avoid limits to configuration that might cause you to eject from + [create-react-app](https://github.com/facebookincubator/create-react-app). + +See [configuring Jest](Configuration.md#snapshotserializers-array-string) for +more information. + +### `.not` + +If you know how to test something, `.not` lets you test its opposite. For +example, this code tests that the best La Croix flavor is not coconut: + +```js +test('the best flavor is not coconut', () => { + expect(bestLaCroixFlavor()).not.toBe('coconut'); +}); +``` + +### `.resolves` + +##### available in Jest **20.0.0+** + +Use `resolves` to unwrap the value of a fulfilled promise so any other matcher +can be chained. If the promise is rejected the assertion fails. + +For example, this code tests that the promise resolves and that the resulting +value is `'lemon'`: + +```js +test('resolves to lemon', () => { + // make sure to add a return statement + return expect(Promise.resolve('lemon')).resolves.toBe('lemon'); +}); +``` + +Note that, since you are still testing promises, the test is still asynchronous. +Hence, you will need to [tell Jest to wait](TestingAsyncCode.md#promises) by +returning the unwrapped assertion. + +Alternatively, you can use `async/await` in combination with `.resolves`: + +```js +test('resolves to lemon', async () => { + await expect(Promise.resolve('lemon')).resolves.toBe('lemon'); + await expect(Promise.resolve('lemon')).resolves.not.toBe('octopus'); +}); +``` + +### `.rejects` + +##### available in Jest **20.0.0+** + +Use `.rejects` to unwrap the reason of a rejected promise so any other matcher +can be chained. If the promise is fulfilled the assertion fails. + +For example, this code tests that the promise rejects with reason `'octopus'`: + +```js +test('rejects to octopus', () => { + // make sure to add a return statement + return expect(Promise.reject(new Error('octopus'))).rejects.toThrow( + 'octopus', + ); +}); +``` + +Note that, since you are still testing promises, the test is still asynchronous. +Hence, you will need to [tell Jest to wait](TestingAsyncCode.md#promises) by +returning the unwrapped assertion. + +Alternatively, you can use `async/await` in combination with `.rejects`. + +```js +test('rejects to octopus', async () => { + await expect(Promise.reject(new Error('octopus'))).rejects.toThrow('octopus'); +}); +``` + +### `.toBe(value)` + +`toBe` just checks that a value is what you expect. It uses `Object.is` to check +exact equality. + +For example, this code will validate some properties of the `can` object: + +```js +const can = { + name: 'pamplemousse', + ounces: 12, +}; + +describe('the can', () => { + test('has 12 ounces', () => { + expect(can.ounces).toBe(12); + }); + + test('has a sophisticated name', () => { + expect(can.name).toBe('pamplemousse'); + }); +}); +``` + +Don't use `toBe` with floating-point numbers. For example, due to rounding, in +JavaScript `0.2 + 0.1` is not strictly equal to `0.3`. If you have floating +point numbers, try `.toBeCloseTo` instead. + +### `.toHaveBeenCalled()` + +Also under the alias: `.toBeCalled()` + +Use `.toHaveBeenCalled` to ensure that a mock function got called. + +For example, let's say you have a `drinkAll(drink, flavor)` function that takes +a `drink` function and applies it to all available beverages. You might want to +check that `drink` gets called for `'lemon'`, but not for `'octopus'`, because +`'octopus'` flavor is really weird and why would anything be octopus-flavored? +You can do that with this test suite: + +```js +describe('drinkAll', () => { + test('drinks something lemon-flavored', () => { + const drink = jest.fn(); + drinkAll(drink, 'lemon'); + expect(drink).toHaveBeenCalled(); + }); + + test('does not drink something octopus-flavored', () => { + const drink = jest.fn(); + drinkAll(drink, 'octopus'); + expect(drink).not.toHaveBeenCalled(); + }); +}); +``` + +### `.toHaveBeenCalledTimes(number)` + +Use `.toHaveBeenCalledTimes` to ensure that a mock function got called exact +number of times. + +For example, let's say you have a `drinkEach(drink, Array)` function +that takes a `drink` function and applies it to array of passed beverages. You +might want to check that drink function was called exact number of times. You +can do that with this test suite: + +```js +test('drinkEach drinks each drink', () => { + const drink = jest.fn(); + drinkEach(drink, ['lemon', 'octopus']); + expect(drink).toHaveBeenCalledTimes(2); +}); +``` + +### `.toHaveBeenCalledWith(arg1, arg2, ...)` + +Also under the alias: `.toBeCalledWith()` + +Use `.toHaveBeenCalledWith` to ensure that a mock function was called with +specific arguments. + +For example, let's say that you can register a beverage with a `register` +function, and `applyToAll(f)` should apply the function `f` to all registered +beverages. To make sure this works, you could write: + +```js +test('registration applies correctly to orange La Croix', () => { + const beverage = new LaCroix('orange'); + register(beverage); + const f = jest.fn(); + applyToAll(f); + expect(f).toHaveBeenCalledWith(beverage); +}); +``` + +### `.toHaveBeenLastCalledWith(arg1, arg2, ...)` + +Also under the alias: `.lastCalledWith(arg1, arg2, ...)` + +If you have a mock function, you can use `.toHaveBeenLastCalledWith` to test +what arguments it was last called with. For example, let's say you have a +`applyToAllFlavors(f)` function that applies `f` to a bunch of flavors, and you +want to ensure that when you call it, the last flavor it operates on is +`'mango'`. You can write: + +```js +test('applying to all flavors does mango last', () => { + const drink = jest.fn(); + applyToAllFlavors(drink); + expect(drink).toHaveBeenLastCalledWith('mango'); +}); +``` + +### `.toBeCloseTo(number, numDigits)` + +Using exact equality with floating point numbers is a bad idea. Rounding means +that intuitive things fail. For example, this test fails: + +```js +test('adding works sanely with simple decimals', () => { + expect(0.2 + 0.1).toBe(0.3); // Fails! +}); +``` + +It fails because in JavaScript, `0.2 + 0.1` is actually `0.30000000000000004`. +Sorry. + +Instead, use `.toBeCloseTo`. Use `numDigits` to control how many digits after +the decimal point to check. For example, if you want to be sure that `0.2 + 0.1` +is equal to `0.3` with a precision of 5 decimal digits, you can use this test: + +```js +test('adding works sanely with simple decimals', () => { + expect(0.2 + 0.1).toBeCloseTo(0.3, 5); +}); +``` + +The default for `numDigits` is 2, which has proved to be a good default in most +cases. + +### `.toBeDefined()` + +Use `.toBeDefined` to check that a variable is not undefined. For example, if +you just want to check that a function `fetchNewFlavorIdea()` returns +_something_, you can write: + +```js +test('there is a new flavor idea', () => { + expect(fetchNewFlavorIdea()).toBeDefined(); +}); +``` + +You could write `expect(fetchNewFlavorIdea()).not.toBe(undefined)`, but it's +better practice to avoid referring to `undefined` directly in your code. + +### `.toBeFalsy()` + +Use `.toBeFalsy` when you don't care what a value is, you just want to ensure a +value is false in a boolean context. For example, let's say you have some +application code that looks like: + +```js +drinkSomeLaCroix(); +if (!getErrors()) { + drinkMoreLaCroix(); +} +``` + +You may not care what `getErrors` returns, specifically - it might return +`false`, `null`, or `0`, and your code would still work. So if you want to test +there are no errors after drinking some La Croix, you could write: + +```js +test('drinking La Croix does not lead to errors', () => { + drinkSomeLaCroix(); + expect(getErrors()).toBeFalsy(); +}); +``` + +In JavaScript, there are six falsy values: `false`, `0`, `''`, `null`, +`undefined`, and `NaN`. Everything else is truthy. + +### `.toBeGreaterThan(number)` + +To compare floating point numbers, you can use `toBeGreaterThan`. For example, +if you want to test that `ouncesPerCan()` returns a value of more than 10 +ounces, write: + +```js +test('ounces per can is more than 10', () => { + expect(ouncesPerCan()).toBeGreaterThan(10); +}); +``` + +### `.toBeGreaterThanOrEqual(number)` + +To compare floating point numbers, you can use `toBeGreaterThanOrEqual`. For +example, if you want to test that `ouncesPerCan()` returns a value of at least +12 ounces, write: + +```js +test('ounces per can is at least 12', () => { + expect(ouncesPerCan()).toBeGreaterThanOrEqual(12); +}); +``` + +### `.toBeLessThan(number)` + +To compare floating point numbers, you can use `toBeLessThan`. For example, if +you want to test that `ouncesPerCan()` returns a value of less than 20 ounces, +write: + +```js +test('ounces per can is less than 20', () => { + expect(ouncesPerCan()).toBeLessThan(20); +}); +``` + +### `.toBeLessThanOrEqual(number)` + +To compare floating point numbers, you can use `toBeLessThanOrEqual`. For +example, if you want to test that `ouncesPerCan()` returns a value of at most 12 +ounces, write: + +```js +test('ounces per can is at most 12', () => { + expect(ouncesPerCan()).toBeLessThanOrEqual(12); +}); +``` + +### `.toBeInstanceOf(Class)` + +Use `.toBeInstanceOf(Class)` to check that an object is an instance of a class. +This matcher uses `instanceof` underneath. + +```js +class A {} + +expect(new A()).toBeInstanceOf(A); +expect(() => {}).toBeInstanceOf(Function); +expect(new A()).toBeInstanceOf(Function); // throws +``` + +### `.toBeNull()` + +`.toBeNull()` is the same as `.toBe(null)` but the error messages are a bit +nicer. So use `.toBeNull()` when you want to check that something is null. + +```js +function bloop() { + return null; +} + +test('bloop returns null', () => { + expect(bloop()).toBeNull(); +}); +``` + +### `.toBeTruthy()` + +Use `.toBeTruthy` when you don't care what a value is, you just want to ensure a +value is true in a boolean context. For example, let's say you have some +application code that looks like: + +```js +drinkSomeLaCroix(); +if (thirstInfo()) { + drinkMoreLaCroix(); +} +``` + +You may not care what `thirstInfo` returns, specifically - it might return +`true` or a complex object, and your code would still work. So if you just want +to test that `thirstInfo` will be truthy after drinking some La Croix, you could +write: + +```js +test('drinking La Croix leads to having thirst info', () => { + drinkSomeLaCroix(); + expect(thirstInfo()).toBeTruthy(); +}); +``` + +In JavaScript, there are six falsy values: `false`, `0`, `''`, `null`, +`undefined`, and `NaN`. Everything else is truthy. + +### `.toBeUndefined()` + +Use `.toBeUndefined` to check that a variable is undefined. For example, if you +want to check that a function `bestDrinkForFlavor(flavor)` returns `undefined` +for the `'octopus'` flavor, because there is no good octopus-flavored drink: + +```js +test('the best drink for octopus flavor is undefined', () => { + expect(bestDrinkForFlavor('octopus')).toBeUndefined(); +}); +``` + +You could write `expect(bestDrinkForFlavor('octopus')).toBe(undefined)`, but +it's better practice to avoid referring to `undefined` directly in your code. + +### `.toContain(item)` + +Use `.toContain` when you want to check that an item is in an array. For testing +the items in the array, this uses `===`, a strict equality check. `.toContain` +can also check whether a string is a substring of another string. + +For example, if `getAllFlavors()` returns an array of flavors and you want to be +sure that `lime` is in there, you can write: + +```js +test('the flavor list contains lime', () => { + expect(getAllFlavors()).toContain('lime'); +}); +``` + +### `.toContainEqual(item)` + +Use `.toContainEqual` when you want to check that an item with a specific +structure and values is contained in an array. For testing the items in the +array, this matcher recursively checks the equality of all fields, rather than +checking for object identity. + +```js +describe('my beverage', () => { + test('is delicious and not sour', () => { + const myBeverage = {delicious: true, sour: false}; + expect(myBeverages()).toContainEqual(myBeverage); + }); +}); +``` + +### `.toEqual(value)` + +Use `.toEqual` when you want to check that two objects have the same value. This +matcher recursively checks the equality of all fields, rather than checking for +object identity—this is also known as "deep equal". For example, `toEqual` and +`toBe` behave differently in this test suite, so all the tests pass: + +```js +const can1 = { + flavor: 'grapefruit', + ounces: 12, +}; +const can2 = { + flavor: 'grapefruit', + ounces: 12, +}; + +describe('the La Croix cans on my desk', () => { + test('have all the same properties', () => { + expect(can1).toEqual(can2); + }); + test('are not the exact same can', () => { + expect(can1).not.toBe(can2); + }); +}); +``` + +> Note: `.toEqual` won't perform a _deep equality_ check for two errors. Only +> the `message` property of an Error is considered for equality. It is +> recommended to use the `.toThrow` matcher for testing against errors. + +### `.toHaveLength(number)` + +Use `.toHaveLength` to check that an object has a `.length` property and it is +set to a certain numeric value. + +This is especially useful for checking arrays or strings size. + +```js +expect([1, 2, 3]).toHaveLength(3); +expect('abc').toHaveLength(3); +expect('').not.toHaveLength(5); +``` + +### `.toMatch(regexpOrString)` + +Use `.toMatch` to check that a string matches a regular expression. + +For example, you might not know what exactly `essayOnTheBestFlavor()` returns, +but you know it's a really long string, and the substring `grapefruit` should be +in there somewhere. You can test this with: + +```js +describe('an essay on the best flavor', () => { + test('mentions grapefruit', () => { + expect(essayOnTheBestFlavor()).toMatch(/grapefruit/); + expect(essayOnTheBestFlavor()).toMatch(new RegExp('grapefruit')); + }); +}); +``` + +This matcher also accepts a string, which it will try to match: + +```js +describe('grapefruits are healthy', () => { + test('grapefruits are a fruit', () => { + expect('grapefruits').toMatch('fruit'); + }); +}); +``` + +### `.toMatchObject(object)` + +Use `.toMatchObject` to check that a JavaScript object matches a subset of the +properties of an object. It will match received objects with properties that are +**not** in the expected object. + +You can also pass an array of objects, in which case the method will return true +only if each object in the received array matches (in the `toMatchObject` sense +described above) the corresponding object in the expected array. This is useful +if you want to check that two arrays match in their number of elements, as +opposed to `arrayContaining`, which allows for extra elements in the received +array. + +You can match properties against values or against matchers. + +```js +const houseForSale = { + bath: true, + bedrooms: 4, + kitchen: { + amenities: ['oven', 'stove', 'washer'], + area: 20, + wallColor: 'white', + }, +}; +const desiredHouse = { + bath: true, + kitchen: { + amenities: ['oven', 'stove', 'washer'], + wallColor: expect.stringMatching(/white|yellow/), + }, +}; + +test('the house has my desired features', () => { + expect(houseForSale).toMatchObject(desiredHouse); +}); +``` + +```js +describe('toMatchObject applied to arrays arrays', () => { + test('the number of elements must match exactly', () => { + expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}, {baz: 1}]); + }); + + // .arrayContaining "matches a received array which contains elements that + // are *not* in the expected array" + test('.toMatchObject does not allow extra elements', () => { + expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}]); + }); + + test('.toMatchObject is called for each elements, so extra object properties are okay', () => { + expect([{foo: 'bar'}, {baz: 1, extra: 'quux'}]).toMatchObject([ + {foo: 'bar'}, + {baz: 1}, + ]); + }); +}); +``` + +### `.toHaveProperty(keyPath, value)` + +Use `.toHaveProperty` to check if property at provided reference `keyPath` +exists for an object. For checking deeply nested properties in an object you may +use +[dot notation](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors) +or an array containing the keyPath for deep references. + +Optionally, you can provide a `value` to check if it's equal to the value +present at `keyPath` on the target object. This matcher uses 'deep equality' +(like `toEqual()`) and recursively checks the equality of all fields. + +The following example contains a `houseForSale` object with nested properties. +We are using `toHaveProperty` to check for the existence and values of various +properties in the object. + +```js +// Object containing house features to be tested +const houseForSale = { + bath: true, + bedrooms: 4, + kitchen: { + amenities: ['oven', 'stove', 'washer'], + area: 20, + wallColor: 'white', + 'nice.oven': true, + }, +}; + +test('this house has my desired features', () => { + // Simple Referencing + expect(houseForSale).toHaveProperty('bath'); + expect(houseForSale).toHaveProperty('bedrooms', 4); + + expect(houseForSale).not.toHaveProperty('pool'); + + // Deep referencing using dot notation + expect(houseForSale).toHaveProperty('kitchen.area', 20); + expect(houseForSale).toHaveProperty('kitchen.amenities', [ + 'oven', + 'stove', + 'washer', + ]); + + expect(houseForSale).not.toHaveProperty('kitchen.open'); + + // Deep referencing using an array containing the keyPath + expect(houseForSale).toHaveProperty(['kitchen', 'area'], 20); + expect(houseForSale).toHaveProperty( + ['kitchen', 'amenities'], + ['oven', 'stove', 'washer'], + ); + expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven'); + expect(houseForSale).toHaveProperty(['kitchen', 'nice.oven']); + expect(houseForSale).not.toHaveProperty(['kitchen', 'open']); +}); +``` + +### `.toMatchSnapshot(optionalString)` + +This ensures that a value matches the most recent snapshot. Check out +[the Snapshot Testing guide](SnapshotTesting.md) for more information. + +You can also specify an optional snapshot name. Otherwise, the name is inferred +from the test. + +_Note: While snapshot testing is most commonly used with React components, any +serializable value can be used as a snapshot._ + +### `.toThrow(error)` + +Also under the alias: `.toThrowError(error)` + +Use `.toThrow` to test that a function throws when it is called. For example, if +we want to test that `drinkFlavor('octopus')` throws, because octopus flavor is +too disgusting to drink, we could write: + +```js +test('throws on octopus', () => { + expect(() => { + drinkFlavor('octopus'); + }).toThrow(); +}); +``` + +If you want to test that a specific error gets thrown, you can provide an +argument to `toThrow`. The argument can be a string for the error message, a +class for the error, or a regex that should match the error. For example, let's +say that `drinkFlavor` is coded like this: + +```js +function drinkFlavor(flavor) { + if (flavor == 'octopus') { + throw new DisgustingFlavorError('yuck, octopus flavor'); + } + // Do some other stuff +} +``` + +We could test this error gets thrown in several ways: + +```js +test('throws on octopus', () => { + function drinkOctopus() { + drinkFlavor('octopus'); + } + + // Test the exact error message + expect(drinkOctopus).toThrowError('yuck, octopus flavor'); + + // Test that the error message says "yuck" somewhere + expect(drinkOctopus).toThrowError(/yuck/); + + // Test that we get a DisgustingFlavorError + expect(drinkOctopus).toThrowError(DisgustingFlavorError); +}); +``` + +> Note: You must wrap the code in a function, otherwise the error will not be +> caught and the assertion will fail. + +### `.toThrowErrorMatchingSnapshot()` + +Use `.toThrowErrorMatchingSnapshot` to test that a function throws an error +matching the most recent snapshot when it is called. For example, let's say you +have a `drinkFlavor` function that throws whenever the flavor is `'octopus'`, +and is coded like this: + +```js +function drinkFlavor(flavor) { + if (flavor == 'octopus') { + throw new DisgustingFlavorError('yuck, octopus flavor'); + } + // Do some other stuff +} +``` + +The test for this function will look this way: + +```js +test('throws on octopus', () => { + function drinkOctopus() { + drinkFlavor('octopus'); + } + + expect(drinkOctopus).toThrowErrorMatchingSnapshot(); +}); +``` + +And it will generate the following snapshot: + +```js +exports[`drinking flavors throws on octopus 1`] = `"yuck, octopus flavor"`; +``` + +Check out +[React Tree Snapshot Testing](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html) +for more information on snapshot testing. diff --git a/website/versioned_docs/version-22.4/GettingStarted.md b/website/versioned_docs/version-22.4/GettingStarted.md new file mode 100644 index 000000000000..8e7f5ece6734 --- /dev/null +++ b/website/versioned_docs/version-22.4/GettingStarted.md @@ -0,0 +1,156 @@ +--- +id: version-22.4-getting-started +title: Getting Started +original_id: getting-started +--- + +Install Jest using [`yarn`](https://yarnpkg.com/en/package/jest): + +```bash +yarn add --dev jest +``` + +Or [`npm`](https://www.npmjs.com/): + +```bash +npm install --save-dev jest +``` + +Let's get started by writing a test for a hypothetical function that adds two +numbers. First, create a `sum.js` file: + +```javascript +function sum(a, b) { + return a + b; +} +module.exports = sum; +``` + +Then, create a file named `sum.test.js`. This will contain our actual test: + +```javascript +const sum = require('./sum'); + +test('adds 1 + 2 to equal 3', () => { + expect(sum(1, 2)).toBe(3); +}); +``` + +Add the following section to your `package.json`: + +```json +{ + "scripts": { + "test": "jest" + } +} +``` + +Finally, run `yarn test` and Jest will print this message: + +```bash +PASS ./sum.test.js +✓ adds 1 + 2 to equal 3 (5ms) +``` + +**You just successfully wrote your first test using Jest!** + +This test used `expect` and `toBe` to test that two values were exactly +identical. To learn about the other things that Jest can test, see +[Using Matchers](UsingMatchers.md). + +## Running from command line + +You can run Jest directly from the CLI (if it's globally available in your +`PATH`, e.g. by `yarn global add jest`) with variety of useful options. + +Here's how to run Jest on files matching `my-test`, using `config.json` as a +configuration file and display a native OS notification after the run: + +```bash +jest my-test --notify --config=config.json +``` + +If you'd like to learn more about running `jest` through the command line, take +a look at the [Jest CLI Options](CLI.md) page. + +## Additional Configuration + +### Using Babel + +To use [Babel](http://babeljs.io/), install the `babel-jest` and +`regenerator-runtime` packages: + +```bash +yarn add --dev babel-jest babel-core regenerator-runtime +``` + +> Note: If you are using a babel version 7 then you need to install `babel-jest` +> with the following command: +> +> ```bash +> yarn add --dev babel-jest 'babel-core@^7.0.0-0' @babel/core regenerator-runtime +> ``` + +_Note: Explicitly installing `regenerator-runtime` is not needed if you use +`npm` 3 or 4 or Yarn_ + +Don't forget to add a [`.babelrc`](https://babeljs.io/docs/usage/babelrc/) file +in your project's root folder. For example, if you are using ES6 and +[React.js](https://facebook.github.io/react/) with the +[`babel-preset-env`](https://babeljs.io/docs/plugins/preset-env/) and +[`babel-preset-react`](https://babeljs.io/docs/plugins/preset-react/) presets: + +```json +{ + "presets": ["env", "react"] +} +``` + +You are now set up to use all ES6 features and React specific syntax. + +> Note: If you are using a more complicated Babel configuration, using Babel's +> `env` option, keep in mind that Jest will automatically define `NODE_ENV` as +> `test`. It will not use `development` section like Babel does by default when +> no `NODE_ENV` is set. + +> Note: If you've turned off transpilation of ES6 modules with the option +> `{ "modules": false }`, you have to make sure to turn this on in your test +> environment. + +```json +{ + "presets": [["env", {"modules": false}], "react"], + "env": { + "test": { + "presets": [["env"], "react"] + } + } +} +``` + +> Note: `babel-jest` is automatically installed when installing Jest and will +> automatically transform files if a babel configuration exists in your project. +> To avoid this behavior, you can explicitly reset the `transform` configuration +> option: + +```json +// package.json +{ + "jest": { + "transform": {} + } +} +``` + +### Using webpack + +Jest can be used in projects that use [webpack](https://webpack.github.io/) to +manage assets, styles, and compilation. webpack does offer some unique +challenges over other tools. Refer to the [webpack guide](Webpack.md) to get +started. + +### Using TypeScript + +To use TypeScript in your tests you can use +[ts-jest](https://github.com/kulshekhar/ts-jest). diff --git a/website/versioned_docs/version-22.4/JestCommunity.md b/website/versioned_docs/version-22.4/JestCommunity.md new file mode 100644 index 000000000000..afbe88026529 --- /dev/null +++ b/website/versioned_docs/version-22.4/JestCommunity.md @@ -0,0 +1,32 @@ +--- +title: Jest Community +id: version-22.4-jest-community +original_id: jest-community +--- + +The community around Jest is working hard to make the testing experience even +greater. + +[jest-community](https://github.com/jest-community) is a new GitHub organization +for high quality Jest additions curated by Jest maintainers and collaborators. +It already features some of our favorite projects, to name a few: + +* [vscode-jest](https://github.com/jest-community/vscode-jest) +* [jest-extended](https://github.com/jest-community/jest-extended) +* [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) +* [awesome-jest](https://github.com/jest-community/awesome-jest) + +Community projects under one organisation are a great way for Jest to experiment +with new ideas/techniques and approaches. Encourage contributions from the +community and publish contributions independently at a faster pace. + +The jest-community org maintains an +[awesome-jest](https://github.com/jest-community/awesome-jest) list of great +projects and resources related to Jest, this includes all projects not just the +ones in the jest-community org. + +If you have something awesome to share, feel free to reach out to us! We'd love +to share your project on the awesome-jest list +([send a PR here](https://github.com/jest-community/awesome-jest/pulls)) or if +you would like to transfer your project to the jest-community org reachout to +one of the owners of the org. diff --git a/website/versioned_docs/version-22.4/JestObjectAPI.md b/website/versioned_docs/version-22.4/JestObjectAPI.md new file mode 100644 index 000000000000..16720f2e7f4a --- /dev/null +++ b/website/versioned_docs/version-22.4/JestObjectAPI.md @@ -0,0 +1,568 @@ +--- +id: version-22.4-jest-object +title: The Jest Object +original_id: jest-object +--- + +The `jest` object is automatically in scope within every test file. The methods +in the `jest` object help create mocks and let you control Jest's overall +behavior. + +## Methods + +* [`jest.clearAllTimers()`](#jestclearalltimers) +* [`jest.disableAutomock()`](#jestdisableautomock) +* [`jest.enableAutomock()`](#jestenableautomock) +* [`jest.fn(implementation)`](#jestfnimplementation) +* [`jest.isMockFunction(fn)`](#jestismockfunctionfn) +* [`jest.genMockFromModule(moduleName)`](#jestgenmockfrommodulemodulename) +* [`jest.mock(moduleName, factory, options)`](#jestmockmodulename-factory-options) +* [`jest.unmock(moduleName)`](#jestunmockmodulename) +* [`jest.doMock(moduleName, factory, options)`](#jestdomockmodulename-factory-options) +* [`jest.dontMock(moduleName)`](#jestdontmockmodulename) +* [`jest.clearAllMocks()`](#jestclearallmocks) +* [`jest.resetAllMocks()`](#jestresetallmocks) +* [`jest.restoreAllMocks()`](#jestrestoreallmocks) +* [`jest.resetModules()`](#jestresetmodules) +* [`jest.runAllTicks()`](#jestrunallticks) +* [`jest.runAllTimers()`](#jestrunalltimers) +* [`jest.advanceTimersByTime(msToRun)`](#jestadvancetimersbytimemstorun) +* [`jest.runOnlyPendingTimers()`](#jestrunonlypendingtimers) +* [`jest.setMock(moduleName, moduleExports)`](#jestsetmockmodulename-moduleexports) +* [`jest.setTimeout(timeout)`](#jestsettimeouttimeout) +* [`jest.useFakeTimers()`](#jestusefaketimers) +* [`jest.useRealTimers()`](#jestuserealtimers) +* [`jest.spyOn(object, methodName)`](#jestspyonobject-methodname) +* [`jest.spyOn(object, methodName, accessType?)`](#jestspyonobject-methodname-accesstype) + +--- + +## Reference + +### `jest.clearAllTimers()` + +Removes any pending timers from the timer system. + +This means, if any timers have been scheduled (but have not yet executed), they +will be cleared and will never have the opportunity to execute in the future. + +### `jest.disableAutomock()` + +Disables automatic mocking in the module loader. + +> See `automock` section of [configuration](Configuration.md#automock-boolean) +> for more information + +After this method is called, all `require()`s will return the real versions of +each module (rather than a mocked version). + +Jest configuration: + +```json +"automock": true +``` + +Example: + +```js +// utils.js +export default { + authorize: () => { + return 'token'; + }, +}; +``` + +```js +// __tests__/disableAutomocking.js +import utils from '../utils'; + +jest.disableAutomock(); + +test('original implementation', () => { + // now we have the original implementation, + // even if we set the automocking in a jest configuration + expect(utils.authorize()).toBe('token'); +}); +``` + +This is usually useful when you have a scenario where the number of dependencies +you want to mock is far less than the number of dependencies that you don't. For +example, if you're writing a test for a module that uses a large number of +dependencies that can be reasonably classified as "implementation details" of +the module, then you likely do not want to mock them. + +Examples of dependencies that might be considered "implementation details" are +things ranging from language built-ins (e.g. Array.prototype methods) to highly +common utility methods (e.g. underscore/lo-dash, array utilities etc) and entire +libraries like React.js. + +Returns the `jest` object for chaining. + +_Note: this method was previously called `autoMockOff`. When using `babel-jest`, +calls to `disableAutomock` will automatically be hoisted to the top of the code +block. Use `autoMockOff` if you want to explicitly avoid this behavior._ + +### `jest.enableAutomock()` + +Enables automatic mocking in the module loader. + +Returns the `jest` object for chaining. + +> See `automock` section of [configuration](Configuration.md#automock-boolean) +> for more information + +Example: + +```js +// utils.js +export default { + authorize: () => { + return 'token'; + }, + isAuthorized: secret => secret === 'wizard', +}; +``` + +```js +// __tests__/disableAutomocking.js +jest.enableAutomock(); + +import utils from '../utils'; + +test('original implementation', () => { + // now we have the mocked implementation, + expect(utils.authorize._isMockFunction).toBeTruthy(); + expect(utils.isAuthorized._isMockFunction).toBeTruthy(); +}); +``` + +_Note: this method was previously called `autoMockOn`. When using `babel-jest`, +calls to `enableAutomock` will automatically be hoisted to the top of the code +block. Use `autoMockOn` if you want to explicitly avoid this behavior._ + +### `jest.fn(implementation)` + +Returns a new, unused [mock function](MockFunctionAPI.md). Optionally takes a +mock implementation. + +```js +const mockFn = jest.fn(); +mockFn(); +expect(mockFn).toHaveBeenCalled(); + +// With a mock implementation: +const returnsTrue = jest.fn(() => true); +console.log(returnsTrue()); // true; +``` + +### `jest.isMockFunction(fn)` + +Determines if the given function is a mocked function. + +### `jest.genMockFromModule(moduleName)` + +Given the name of a module, use the automatic mocking system to generate a +mocked version of the module for you. + +This is useful when you want to create a [manual mock](ManualMocks.md) that +extends the automatic mock's behavior. + +Example: + +```js +// utils.js +export default { + authorize: () => { + return 'token'; + }, + isAuthorized: secret => secret === 'wizard', +}; +``` + +```js +// __tests__/genMockFromModule.test.js +const utils = jest.genMockFromModule('../utils').default; +utils.isAuthorized = jest.fn(secret => secret === 'not wizard'); + +test('implementation created by jest.genMockFromModule', () => { + expect(utils.authorize.mock).toBeTruthy(); + expect(utils.isAuthorized('not wizard')).toEqual(true); +}); +``` + +### `jest.mock(moduleName, factory, options)` + +Mocks a module with an auto-mocked version when it is being required. `factory` +and `options` are optional. For example: + +```js +// banana.js +module.exports = () => 'banana'; + +// __tests__/test.js +jest.mock('../banana'); + +const banana = require('../banana'); // banana will be explicitly mocked. + +banana(); // will return 'undefined' because the function is auto-mocked. +``` + +The second argument can be used to specify an explicit module factory that is +being run instead of using Jest's automocking feature: + +```js +jest.mock('../moduleName', () => { + return jest.fn(() => 42); +}); + +// This runs the function specified as second argument to `jest.mock`. +const moduleName = require('../moduleName'); +moduleName(); // Will return '42'; +``` + +The third argument can be used to create virtual mocks – mocks of modules that +don't exist anywhere in the system: + +```js +jest.mock( + '../moduleName', + () => { + /* + * Custom implementation of a module that doesn't exist in JS, + * like a generated module or a native module in react-native. + */ + }, + {virtual: true}, +); +``` + +_Warning: Importing a module in a setup file (as specified by +`setupTestFrameworkScriptFile`) will prevent mocking for the module in question, +as well as all the modules that it imports._ + +Modules that are mocked with `jest.mock` are mocked only for the file that calls +`jest.mock`. Another file that imports the module will get the original +implementation even if it runs after the test file that mocks the module. + +Returns the `jest` object for chaining. + +### `jest.unmock(moduleName)` + +Indicates that the module system should never return a mocked version of the +specified module from `require()` (e.g. that it should always return the real +module). + +The most common use of this API is for specifying the module a given test +intends to be testing (and thus doesn't want automatically mocked). + +Returns the `jest` object for chaining. + +### `jest.doMock(moduleName, factory, options)` + +When using `babel-jest`, calls to `mock` will automatically be hoisted to the +top of the code block. Use this method if you want to explicitly avoid this +behavior. + +One example when this is useful is when you want to mock a module differently +within the same file: + +```js +beforeEach(() => { + jest.resetModules(); +}); + +test('moduleName 1', () => { + jest.doMock('../moduleName', () => { + return jest.fn(() => 1); + }); + const moduleName = require('../moduleName'); + expect(moduleName()).toEqual(1); +}); + +test('moduleName 2', () => { + jest.doMock('../moduleName', () => { + return jest.fn(() => 2); + }); + const moduleName = require('../moduleName'); + expect(moduleName()).toEqual(2); +}); +``` + +Returns the `jest` object for chaining. + +### `jest.dontMock(moduleName)` + +When using `babel-jest`, calls to `unmock` will automatically be hoisted to the +top of the code block. Use this method if you want to explicitly avoid this +behavior. + +Returns the `jest` object for chaining. + +### `jest.clearAllMocks()` + +Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent +to calling `.mockClear()` on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.resetAllMocks()` + +Resets the state of all mocks. Equivalent to calling `.mockReset()` on every +mocked function. + +Returns the `jest` object for chaining. + +### `jest.restoreAllMocks()` + +##### available in Jest **21.1.0+** + +Restores all mocks back to their original value. Equivalent to calling +`.mockRestore` on every mocked function. Beware that `jest.restoreAllMocks()` +only works when mock was created with `jest.spyOn`; other mocks will require you +to manually restore them. + +### `jest.resetModules()` + +Resets the module registry - the cache of all required modules. This is useful +to isolate modules where local state might conflict between tests. + +Example: + +```js +const sum1 = require('../sum'); +jest.resetModules(); +const sum2 = require('../sum'); +sum1 === sum2; +// > false (Both sum modules are separate "instances" of the sum module.) +``` + +Example in a test: + +```js +beforeEach(() => { + jest.resetModules(); +}); + +test('works', () => { + const sum = require('../sum'); +}); + +test('works too', () => { + const sum = require('../sum'); + // sum is a different copy of the sum module from the previous test. +}); +``` + +Returns the `jest` object for chaining. + +### `jest.runAllTicks()` + +Exhausts the **micro**-task queue (usually interfaced in node via +`process.nextTick`). + +When this API is called, all pending micro-tasks that have been queued via +`process.nextTick` will be executed. Additionally, if those micro-tasks +themselves schedule new micro-tasks, those will be continually exhausted until +there are no more micro-tasks remaining in the queue. + +### `jest.runAllTimers()` + +Exhausts the **macro**-task queue (i.e., all tasks queued by `setTimeout()`, +`setInterval()`, and `setImmediate()`). + +When this API is called, all pending "macro-tasks" that have been queued via +`setTimeout()` or `setInterval()` will be executed. Additionally if those +macro-tasks themselves schedule new macro-tasks, those will be continually +exhausted until there are no more macro-tasks remaining in the queue. + +This is often useful for synchronously executing setTimeouts during a test in +order to synchronously assert about some behavior that would only happen after +the `setTimeout()` or `setInterval()` callbacks executed. See the +[Timer mocks](TimerMocks.md) doc for more information. + +### `jest.runAllImmediates()` + +Exhausts all tasks queued by `setImmediate()`. + +### `jest.advanceTimersByTime(msToRun)` + +##### renamed in Jest **22.0.0+** + +Also under the alias: `.runTimersToTime()` + +Executes only the macro task queue (i.e. all tasks queued by `setTimeout()` or +`setInterval()` and `setImmediate()`). + +When this API is called, all timers are advanced by `msToRun` milliseconds. All +pending "macro-tasks" that have been queued via `setTimeout()` or +`setInterval()`, and would be executed within this time frame will be executed. +Additionally if those macro-tasks schedule new macro-tasks that would be +executed within the same time frame, those will be executed until there are no +more macro-tasks remaining in the queue, that should be run within `msToRun` +milliseconds. + +### `jest.runOnlyPendingTimers()` + +Executes only the macro-tasks that are currently pending (i.e., only the tasks +that have been queued by `setTimeout()` or `setInterval()` up to this point). If +any of the currently pending macro-tasks schedule new macro-tasks, those new +tasks will not be executed by this call. + +This is useful for scenarios such as one where the module being tested schedules +a `setTimeout()` whose callback schedules another `setTimeout()` recursively +(meaning the scheduling never stops). In these scenarios, it's useful to be able +to run forward in time by a single step at a time. + +### `jest.setMock(moduleName, moduleExports)` + +Explicitly supplies the mock object that the module system should return for the +specified module. + +On occasion there are times where the automatically generated mock the module +system would normally provide you isn't adequate enough for your testing needs. +Normally under those circumstances you should write a +[manual mock](ManualMocks.md) that is more adequate for the module in question. +However, on extremely rare occasions, even a manual mock isn't suitable for your +purposes and you need to build the mock yourself inside your test. + +In these rare scenarios you can use this API to manually fill the slot in the +module system's mock-module registry. + +Returns the `jest` object for chaining. + +_Note It is recommended to use +[`jest.mock()`](#jestmockmodulename-factory-options) instead. The `jest.mock` +API's second argument is a module factory instead of the expected exported +module object._ + +### `jest.setTimeout(timeout)` + +Set the default timeout interval for tests and before/after hooks in +milliseconds. + +_Note: The default timeout interval is 5 seconds if this method is not called._ + +Example: + +```js +jest.setTimeout(1000); // 1 second +``` + +### `jest.useFakeTimers()` + +Instructs Jest to use fake versions of the standard timer functions +(`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `nextTick`, +`setImmediate` and `clearImmediate`). + +Returns the `jest` object for chaining. + +### `jest.useRealTimers()` + +Instructs Jest to use the real versions of the standard timer functions. + +Returns the `jest` object for chaining. + +### `jest.spyOn(object, methodName)` + +##### available in Jest **19.0.0+** + +Creates a mock function similar to `jest.fn` but also tracks calls to +`object[methodName]`. Returns a Jest mock function. + +_Note: By default, `jest.spyOn` also calls the **spied** method. This is +different behavior from most other test libraries. If you want to overwrite the +original function, you can use +`jest.spyOn(object, methodName).mockImplementation(() => customImplementation)` +or `object[methodName] = jest.fn(() => customImplementation);`_ + +Example: + +```js +const video = { + play() { + return true; + }, +}; + +module.exports = video; +``` + +Example test: + +```js +const video = require('./video'); + +test('plays video', () => { + const spy = jest.spyOn(video, 'play'); + const isPlaying = video.play(); + + expect(spy).toHaveBeenCalled(); + expect(isPlaying).toBe(true); + + spy.mockReset(); + spy.mockRestore(); +}); +``` + +### `jest.spyOn(object, methodName, accessType?)` + +##### available in Jest **22.1.0+** + +Since Jest 22.1.0+, the `jest.spyOn` method takes an optional third argument of +`accessType` that can be either `'get'` or `'set'`, which proves to be useful +when you want to spy on a getter or a setter, respectively. + +Example: + +```js +const video = { + // it's a getter! + get play() { + return true; + }, +}; + +module.exports = video; + +const audio = { + _volume: false, + // it's a setter! + set volume(value) { + this._volume = value; + }, + get volume() { + return this._volume; + }, +}; + +module.exports = video; +``` + +Example test: + +```js +const video = require('./video'); + +test('plays video', () => { + const spy = jest.spyOn(video, 'play', 'get'); // we pass 'get' + const isPlaying = video.play; + + expect(spy).toHaveBeenCalled(); + expect(isPlaying).toBe(true); + + spy.mockReset(); + spy.mockRestore(); +}); + +test('plays audio', () => { + const spy = jest.spyOn(video, 'play', 'set'); // we pass 'set' + video.volume = 100; + + expect(spy).toHaveBeenCalled(); + expect(video.volume).toBe(100); + + spy.mockReset(); + spy.mockRestore(); +}); +``` diff --git a/website/versioned_docs/version-22.4/ManualMocks.md b/website/versioned_docs/version-22.4/ManualMocks.md new file mode 100644 index 000000000000..4e58bfacebe8 --- /dev/null +++ b/website/versioned_docs/version-22.4/ManualMocks.md @@ -0,0 +1,180 @@ +--- +id: version-22.4-manual-mocks +title: Manual Mocks +original_id: manual-mocks +--- + +Manual mocks are used to stub out functionality with mock data. For example, +instead of accessing a remote resource like a website or a database, you might +want to create a manual mock that allows you to use fake data. This ensures your +tests will be fast and not flaky. + +### Mocking user modules + +Manual mocks are defined by writing a module in a `__mocks__/` subdirectory +immediately adjacent to the module. For example, to mock a module called `user` +in the `models` directory, create a file called `user.js` and put it in the +`models/__mocks__` directory. Note that the `__mocks__` folder is +case-sensitive, so naming the directory `__MOCKS__` will break on some systems. + +> When we require that module in our tests, then explicitly calling +> `jest.mock('./moduleName')` is **required**. + +### Mocking Node modules + +If the module you are mocking is a Node module (e.g.: `lodash`), the mock should +be placed in the `__mocks__` directory adjacent to `node_modules` (unless you +configured [`roots`](Configuration.md#roots-array-string) to point to a folder +other than the project root) and will be **automatically** mocked. There's no +need to explicitly call `jest.mock('module_name')`. + +Scoped modules can be mocked by creating a file in a directory structure that +matches the name of the scoped module. For example, to mock a scoped module +called `@scope/project-name`, create a file at +`__mocks__/@scope/project-name.js`, creating the `@scope/` directory +accordingly. + +> Warning: If we want to mock Node's core modules (e.g.: `fs` or `path`), then +> explicitly calling e.g. `jest.mock('path')` is **required**, because core Node +> modules are not mocked by default. + +### Examples + +```bash +. +├── config +├── __mocks__ +│   └── fs.js +├── models +│   ├── __mocks__ +│   │   └── user.js +│   └── user.js +├── node_modules +└── views +``` + +When a manual mock exists for a given module, Jest's module system will use that +module when explicitly calling `jest.mock('moduleName')`. However, manual mocks +will take precedence over node modules even if `jest.mock('moduleName')` is not +called. To opt out of this behavior you will need to explicitly call +`jest.unmock('moduleName')` in tests that should use the actual module +implementation. + +Here's a contrived example where we have a module that provides a summary of all +the files in a given directory. In this case we use the core (built in) `fs` +module. + +```javascript +// FileSummarizer.js +'use strict'; + +const fs = require('fs'); + +function summarizeFilesInDirectorySync(directory) { + return fs.readdirSync(directory).map(fileName => ({ + directory, + fileName, + })); +} + +exports.summarizeFilesInDirectorySync = summarizeFilesInDirectorySync; +``` + +Since we'd like our tests to avoid actually hitting the disk (that's pretty slow +and fragile), we create a manual mock for the `fs` module by extending an +automatic mock. Our manual mock will implement custom versions of the `fs` APIs +that we can build on for our tests: + +```javascript +// __mocks__/fs.js +'use strict'; + +const path = require('path'); + +const fs = jest.genMockFromModule('fs'); + +// This is a custom function that our tests can use during setup to specify +// what the files on the "mock" filesystem should look like when any of the +// `fs` APIs are used. +let mockFiles = Object.create(null); +function __setMockFiles(newMockFiles) { + mockFiles = Object.create(null); + for (const file in newMockFiles) { + const dir = path.dirname(file); + + if (!mockFiles[dir]) { + mockFiles[dir] = []; + } + mockFiles[dir].push(path.basename(file)); + } +} + +// A custom version of `readdirSync` that reads from the special mocked out +// file list set via __setMockFiles +function readdirSync(directoryPath) { + return mockFiles[directoryPath] || []; +} + +fs.__setMockFiles = __setMockFiles; +fs.readdirSync = readdirSync; + +module.exports = fs; +``` + +Now we write our test. Note that we need to explicitly tell that we want to mock +the `fs` module because it’s a core Node module: + +```javascript +// __tests__/FileSummarizer-test.js +'use strict'; + +jest.mock('fs'); + +describe('listFilesInDirectorySync', () => { + const MOCK_FILE_INFO = { + '/path/to/file1.js': 'console.log("file1 contents");', + '/path/to/file2.txt': 'file2 contents', + }; + + beforeEach(() => { + // Set up some mocked out file info before each test + require('fs').__setMockFiles(MOCK_FILE_INFO); + }); + + test('includes all files in the directory in the summary', () => { + const FileSummarizer = require('../FileSummarizer'); + const fileSummary = FileSummarizer.summarizeFilesInDirectorySync( + '/path/to', + ); + + expect(fileSummary.length).toBe(2); + }); +}); +``` + +The example mock shown here uses +[`jest.genMockFromModule`](JestObjectAPI.md#jestgenmockfrommodulemodulename) to +generate an automatic mock, and overrides its default behavior. This is the +recommended approach, but is completely optional. If you do not want to use the +automatic mock at all, you can simply export your own functions from the mock +file. One downside to fully manual mocks is that they're manual – meaning you +have to manually update them any time the module they are mocking changes. +Because of this, it's best to use or extend the automatic mock when it works for +your needs. + +To ensure that a manual mock and its real implementation stay in sync, it might +be useful to require the real module using `require.requireActual(moduleName)` +in your manual mock and amending it with mock functions before exporting it. + +The code for this example is available at +[examples/manual-mocks](https://github.com/facebook/jest/tree/master/examples/manual-mocks). + +### Using with ES module imports + +If you're using +[ES module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) +then you'll normally be inclined to put your `import` statements at the top of +the test file. But often you need to instruct Jest to use a mock before modules +use it. For this reason, Jest will automatically hoist `jest.mock` calls to the +top of the module (before any imports). To learn more about this and see it in +action, see [this repo](https://github.com/kentcdodds/how-jest-mocking-works). diff --git a/website/versioned_docs/version-22.4/MigrationGuide.md b/website/versioned_docs/version-22.4/MigrationGuide.md new file mode 100644 index 000000000000..654c36c15757 --- /dev/null +++ b/website/versioned_docs/version-22.4/MigrationGuide.md @@ -0,0 +1,48 @@ +--- +id: version-22.4-migration-guide +title: Migrating to Jest +original_id: migration-guide +--- + +If you'd like to try out Jest with an existing codebase, there are a number of +ways to convert to Jest: + +* If you are using Jasmine, or a Jasmine like API (for example + [Mocha](https://mochajs.org)), Jest should be mostly compatible and easy to + migrate to. +* If you are using AVA, Expect.js (by Automattic), Jasmine, Mocha, proxyquire, + Should.js or Tape you can automatically migrate with Jest Codemods (see + below). +* If you like [chai](http://chaijs.com/), you can upgrade to Jest and continue + using chai. However, we recommend trying out Jest's assertions and their + failure messages. Jest Codemods can migrate from chai (see below). + +### jest-codemods + +If you are using [AVA](https://github.com/avajs/ava), +[Chai](https://github.com/chaijs/chai), +[Expect.js (by Automattic)](https://github.com/Automattic/expect.js), +[Jasmine](https://github.com/jasmine/jasmine), +[Mocha](https://github.com/mochajs/mocha), +[proxyquire](https://github.com/thlorenz/proxyquire), +[Should.js](https://github.com/tj/should.js/) or +[Tape](https://github.com/substack/tape) you can use the third-party +[jest-codemods](https://github.com/skovhus/jest-codemods) to do most of the +dirty migration work. It runs a code transformation on your codebase using +[jscodeshift](https://github.com/facebook/jscodeshift). + +Install Jest Codemods with `yarn` by running: + +```bash +yarn global add jest-codemods +``` + +To transform your existing tests, navigate to the project containing the tests +and run: + +```bash +jest-codemods +``` + +More information can be found at +[https://github.com/skovhus/jest-codemods](https://github.com/skovhus/jest-codemods). diff --git a/website/versioned_docs/version-22.4/MockFunctionAPI.md b/website/versioned_docs/version-22.4/MockFunctionAPI.md new file mode 100644 index 000000000000..3d1fd97d4f50 --- /dev/null +++ b/website/versioned_docs/version-22.4/MockFunctionAPI.md @@ -0,0 +1,336 @@ +--- +id: version-22.4-mock-function-api +title: Mock Functions +original_id: mock-function-api +--- + +Mock functions are also known as "spies", because they let you spy on the +behavior of a function that is called indirectly by some other code, rather than +just testing the output. You can create a mock function with `jest.fn()`. If no +implementation is given, the mock function will return `undefined` when invoked. + +## Methods + + + +--- + +## Reference + +### `mockFn.getMockName()` + +##### available in Jest **22.0.0+** + +Returns the mock name string set by calling `mockFn.mockName(value)`. + +### `mockFn.mock.calls` + +An array that represents all calls that have been made into this mock function. +Each call is represented by an array of arguments that were passed during the +call. + +For example: A mock function `f` that has been called twice, with the arguments +`f('arg1', 'arg2')`, and then with the arguments `f('arg3', 'arg4')` would have +a `mock.calls` array that looks like this: + +```js +[['arg1', 'arg2'], ['arg3', 'arg4']]; +``` + +### `mockFn.mock.instances` + +An array that contains all the object instances that have been instantiated from +this mock function using `new`. + +For example: A mock function that has been instantiated twice would have the +following `mock.instances` array: + +```js +const mockFn = jest.fn(); + +const a = new mockFn(); +const b = new mockFn(); + +mockFn.mock.instances[0] === a; // true +mockFn.mock.instances[1] === b; // true +``` + +### `mockFn.mockClear()` + +Resets all information stored in the [`mockFn.mock.calls`](#mockfn-mock-calls) +and [`mockFn.mock.instances`](#mockfn-mock-instances) arrays. + +Often this is useful when you want to clean up a mock's usage data between two +assertions. + +Beware that `mockClear` will replace `mockFn.mock`, not just +[`mockFn.mock.calls`](#mockfn-mock-calls) and +[`mockFn.mock.instances`](#mockfn-mock-instances). You should therefore avoid +assigning `mockFn.mock` to other variables, temporary or not, to make sure you +don't access stale data. + +The [`clearMocks`](configuration.html#clearmocks-boolean) configuration option +is available to clear mocks automatically between tests. + +### `mockFn.mockReset()` + +Resets all information stored in the mock, including any initial implementation +and mock name given. + +This is useful when you want to completely restore a mock back to its initial +state. + +Beware that `mockReset` will replace `mockFn.mock`, not just +[`mockFn.mock.calls`](#mockfn-mock-calls) and +[`mockFn.mock.instances`](#mockfn-mock-instances). You should therefore avoid +assigning `mockFn.mock` to other variables, temporary or not, to make sure you +don't access stale data. + +### `mockFn.mockRestore()` + +Removes the mock and restores the initial implementation. + +This is useful when you want to mock functions in certain test cases and restore +the original implementation in others. + +Beware that `mockFn.mockRestore` only works when mock was created with +`jest.spyOn`. Thus you have to take care of restoration yourself when manually +assigning `jest.fn()`. + +The [`restoreMocks`](configuration.html#restoremocks-boolean) configuration +option is available to restore mocks automatically between tests. + +### `mockFn.mockImplementation(fn)` + +Accepts a function that should be used as the implementation of the mock. The +mock itself will still record all calls that go into and instances that come +from itself – the only difference is that the implementation will also be +executed when the mock is called. + +_Note: `jest.fn(implementation)` is a shorthand for +`jest.fn().mockImplementation(implementation)`._ + +For example: + +```js +const mockFn = jest.fn().mockImplementation(scalar => 42 + scalar); +// or: jest.fn(scalar => 42 + scalar); + +const a = mockFn(0); +const b = mockFn(1); + +a === 42; // true +b === 43; // true + +mockFn.mock.calls[0][0] === 0; // true +mockFn.mock.calls[1][0] === 1; // true +``` + +`mockImplementation` can also be used to mock class constructors: + +```js +// SomeClass.js +module.exports = class SomeClass { + m(a, b) {} +}; + +// OtherModule.test.js +jest.mock('./SomeClass'); // this happens automatically with automocking +const SomeClass = require('./SomeClass'); +const mMock = jest.fn(); +SomeClass.mockImplementation(() => { + return { + m: mMock, + }; +}); + +const some = new SomeClass(); +some.m('a', 'b'); +console.log('Calls to m: ', mMock.mock.calls); +``` + +### `mockFn.mockImplementationOnce(fn)` + +Accepts a function that will be used as an implementation of the mock for one +call to the mocked function. Can be chained so that multiple function calls +produce different results. + +```js +const myMockFn = jest + .fn() + .mockImplementationOnce(cb => cb(null, true)) + .mockImplementationOnce(cb => cb(null, false)); + +myMockFn((err, val) => console.log(val)); // true + +myMockFn((err, val) => console.log(val)); // false +``` + +When the mocked function runs out of implementations defined with +mockImplementationOnce, it will execute the default implementation set with +`jest.fn(() => defaultValue)` or `.mockImplementation(() => defaultValue)` if +they were called: + +```js +const myMockFn = jest + .fn(() => 'default') + .mockImplementationOnce(() => 'first call') + .mockImplementationOnce(() => 'second call'); + +// 'first call', 'second call', 'default', 'default' +console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn()); +``` + +### `mockFn.mockName(value)` + +##### available in Jest **22.0.0+** + +Accepts a string to use in test result output in place of "jest.fn()" to +indicate which mock function is being referenced. + +For example: + +```js +const mockFn = jest.fn().mockName('mockedFunction'); +// mockFn(); +expect(mockFn).toHaveBeenCalled(); +``` + +Will result in this error: + +```bash + expect(mockedFunction).toHaveBeenCalled() + + Expected mock function to have been called. +``` + +### `mockFn.mockReturnThis()` + +Just a simple sugar function for: + +```js +jest.fn(function() { + return this; +}); +``` + +### `mockFn.mockReturnValue(value)` + +Accepts a value that will be returned whenever the mock function is called. + +```js +const mock = jest.fn(); +mock.mockReturnValue(42); +mock(); // 42 +mock.mockReturnValue(43); +mock(); // 43 +``` + +### `mockFn.mockReturnValueOnce(value)` + +Accepts a value that will be returned for one call to the mock function. Can be +chained so that successive calls to the mock function return different values. +When there are no more `mockReturnValueOnce` values to use, calls will return a +value specified by `mockReturnValue`. + +```js +const myMockFn = jest + .fn() + .mockReturnValue('default') + .mockReturnValueOnce('first call') + .mockReturnValueOnce('second call'); + +// 'first call', 'second call', 'default', 'default' +console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn()); +``` + +### `mockFn.mockResolvedValue(value)` + +##### available in Jest **22.2.0+** + +Simple sugar function for: + +```js +jest.fn().mockImplementation(() => Promise.resolve(value)); +``` + +Useful to mock async functions in async tests: + +```js +test('async test', async () => { + const asyncMock = jest.fn().mockResolvedValue(43); + + await asyncMock(); // 43 +}); +``` + +### `mockFn.mockResolvedValueOnce(value)` + +##### available in Jest **22.2.0+** + +Simple sugar function for: + +```js +jest.fn().mockImplementationOnce(() => Promise.resolve(value)); +``` + +Useful to resolve different values over multiple async calls: + +```js +test('async test', async () => { + const asyncMock = jest + .fn() + .mockResolvedValue('default') + .mockResolvedValueOnce('first call') + .mockResolvedValueOnce('second call'); + + await asyncMock(); // first call + await asyncMock(); // second call + await asyncMock(); // default + await asyncMock(); // default +}); +``` + +### `mockFn.mockRejectedValue(value)` + +##### available in Jest **22.2.0+** + +Simple sugar function for: + +```js +jest.fn().mockImplementation(() => Promise.reject(value)); +``` + +Useful to create async mock functions that will always reject: + +```js +test('async test', async () => { + const asyncMock = jest.fn().mockRejectedValue(new Error('Async error')); + + await asyncMock(); // throws "Async error" +}); +``` + +### `mockFn.mockRejectedValueOnce(value)` + +##### available in Jest **22.2.0+** + +Simple sugar function for: + +```js +jest.fn().mockImplementationOnce(() => Promise.reject(value)); +``` + +Example usage: + +```js +test('async test', async () => { + const asyncMock = jest + .fn() + .mockResolvedValueOnce('first call') + .mockRejectedValueOnce(new Error('Async error')); + + await asyncMock(); // first call + await asyncMock(); // throws "Async error" +}); +``` diff --git a/website/versioned_docs/version-22.4/MockFunctions.md b/website/versioned_docs/version-22.4/MockFunctions.md new file mode 100644 index 000000000000..f6b7b5629d63 --- /dev/null +++ b/website/versioned_docs/version-22.4/MockFunctions.md @@ -0,0 +1,324 @@ +--- +id: version-22.4-mock-functions +title: Mock Functions +original_id: mock-functions +--- + +Mock functions make it easy to test the links between code by erasing the actual +implementation of a function, capturing calls to the function (and the +parameters passed in those calls), capturing instances of constructor functions +when instantiated with `new`, and allowing test-time configuration of return +values. + +There are two ways to mock functions: Either by creating a mock function to use +in test code, or writing a [`manual mock`](ManualMocks.md) to override a module +dependency. + +## Using a mock function + +Let's imagine we're testing an implementation of a function `forEach`, which +invokes a callback for each item in a supplied array. + +```javascript +function forEach(items, callback) { + for (let index = 0; index < items.length; index++) { + callback(items[index]); + } +} +``` + +To test this function, we can use a mock function, and inspect the mock's state +to ensure the callback is invoked as expected. + +```javascript +const mockCallback = jest.fn(); +forEach([0, 1], mockCallback); + +// The mock function is called twice +expect(mockCallback.mock.calls.length).toBe(2); + +// The first argument of the first call to the function was 0 +expect(mockCallback.mock.calls[0][0]).toBe(0); + +// The first argument of the second call to the function was 1 +expect(mockCallback.mock.calls[1][0]).toBe(1); +``` + +## `.mock` property + +All mock functions have this special `.mock` property, which is where data about +how the function has been called is kept. The `.mock` property also tracks the +value of `this` for each call, so it is possible to inspect this as well: + +```javascript +const myMock = jest.fn(); + +const a = new myMock(); +const b = {}; +const bound = myMock.bind(b); +bound(); + +console.log(myMock.mock.instances); +// > [ , ] +``` + +These mock members are very useful in tests to assert how these functions get +called, or instantiated: + +```javascript +// The function was called exactly once +expect(someMockFunction.mock.calls.length).toBe(1); + +// The first arg of the first call to the function was 'first arg' +expect(someMockFunction.mock.calls[0][0]).toBe('first arg'); + +// The second arg of the first call to the function was 'second arg' +expect(someMockFunction.mock.calls[0][1]).toBe('second arg'); + +// This function was instantiated exactly twice +expect(someMockFunction.mock.instances.length).toBe(2); + +// The object returned by the first instantiation of this function +// had a `name` property whose value was set to 'test' +expect(someMockFunction.mock.instances[0].name).toEqual('test'); +``` + +## Mock Return Values + +Mock functions can also be used to inject test values into your code during a +test: + +```javascript +const myMock = jest.fn(); +console.log(myMock()); +// > undefined + +myMock + .mockReturnValueOnce(10) + .mockReturnValueOnce('x') + .mockReturnValue(true); + +console.log(myMock(), myMock(), myMock(), myMock()); +// > 10, 'x', true, true +``` + +Mock functions are also very effective in code that uses a functional +continuation-passing style. Code written in this style helps avoid the need for +complicated stubs that recreate behavior of the real component they're standing +in for, in favor of injecting values directly into the test right before they're +used. + +```javascript +const filterTestFn = jest.fn(); + +// Make the mock return `true` for the first call, +// and `false` for the second call +filterTestFn.mockReturnValueOnce(true).mockReturnValueOnce(false); + +const result = [11, 12].filter(filterTestFn); + +console.log(result); +// > [11] +console.log(filterTestFn.mock.calls); +// > [ [11], [12] ] +``` + +Most real-world examples actually involve getting ahold of a mock function on a +dependent component and configuring that, but the technique is the same. In +these cases, try to avoid the temptation to implement logic inside of any +function that's not directly being tested. + +## Mocking Modules + +Suppose we have a class that fetches users from our API. The class uses +[axios](https://github.com/axios/axios) to call the API then returns the `data` +attribute which contains all the users: + +```js +// users.js +import axios from 'axios'; + +class Users { + static all() { + return axios.get('/users.json').then(resp => resp.data); + } +} + +export default Users; +``` + +Now, in order to test this method without actually hitting the API (and thus +creating slow and fragile tests), we can use the `jest.mock(...)` function to +automatically mock the axios module. + +Once we mock the module we can provide a `mockReturnValue` for `.get` that +returns the data we want our test to assert against. In effect, we are saying +that we want axios.get('/users.json') to return a fake response. + +```js +// users.test.js +import axios from 'axios'; +import Users from './users'; + +jest.mock('axios'); + +test('should fetch users', () => { + const resp = {data: [{name: 'Bob'}]}; + axios.get.mockResolvedValue(resp); + + // or you could use the follwing depending on your use case: + // axios.get.mockImpementation(() => Promise.resolve(resp)) + + return Users.all().then(users => expect(users).toEqual(resp.data)); +}); +``` + +## Mock Implementations + +Still, there are cases where it's useful to go beyond the ability to specify +return values and full-on replace the implementation of a mock function. This +can be done with `jest.fn` or the `mockImplementationOnce` method on mock +functions. + +```javascript +const myMockFn = jest.fn(cb => cb(null, true)); + +myMockFn((err, val) => console.log(val)); +// > true + +myMockFn((err, val) => console.log(val)); +// > true +``` + +The `mockImplementation` method is useful when you need to define the default +implementation of a mock function that is created from another module: + +```js +// foo.js +module.exports = function() { + // some implementation; +}; + +// test.js +jest.mock('../foo'); // this happens automatically with automocking +const foo = require('../foo'); + +// foo is a mock function +foo.mockImplementation(() => 42); +foo(); +// > 42 +``` + +When you need to recreate a complex behavior of a mock function such that +multiple function calls produce different results, use the +`mockImplementationOnce` method: + +```javascript +const myMockFn = jest + .fn() + .mockImplementationOnce(cb => cb(null, true)) + .mockImplementationOnce(cb => cb(null, false)); + +myMockFn((err, val) => console.log(val)); +// > true + +myMockFn((err, val) => console.log(val)); +// > false +``` + +When the mocked function runs out of implementations defined with +`mockImplementationOnce`, it will execute the default implementation set with +`jest.fn` (if it is defined): + +```javascript +const myMockFn = jest + .fn(() => 'default') + .mockImplementationOnce(() => 'first call') + .mockImplementationOnce(() => 'second call'); + +console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn()); +// > 'first call', 'second call', 'default', 'default' +``` + +For cases where we have methods that are typically chained (and thus always need +to return `this`), we have a sugary API to simplify this in the form of a +`.mockReturnThis()` function that also sits on all mocks: + +```javascript +const myObj = { + myMethod: jest.fn().mockReturnThis(), +}; + +// is the same as + +const otherObj = { + myMethod: jest.fn(function() { + return this; + }), +}; +``` + +## Mock Names + +##### available in Jest **22.0.0+** + +You can optionally provide a name for your mock functions, which will be +displayed instead of "jest.fn()" in test error output. Use this if you want to +be able to quickly identify the mock function reporting an error in your test +output. + +```javascript +const myMockFn = jest + .fn() + .mockReturnValue('default') + .mockImplementation(scalar => 42 + scalar) + .mockName('add42'); +``` + +## Custom Matchers + +Finally, in order to make it simpler to assert how mock functions have been +called, we've added some custom matcher functions for you: + +```javascript +// The mock function was called at least once +expect(mockFunc).toBeCalled(); + +// The mock function was called at least once with the specified args +expect(mockFunc).toBeCalledWith(arg1, arg2); + +// The last call to the mock function was called with the specified args +expect(mockFunc).lastCalledWith(arg1, arg2); + +// All calls and the name of the mock is written as a snapshot +expect(mockFunc).toMatchSnapshot(); +``` + +These matchers are really just sugar for common forms of inspecting the `.mock` +property. You can always do this manually yourself if that's more to your taste +or if you need to do something more specific: + +```javascript +// The mock function was called at least once +expect(mockFunc.mock.calls.length).toBeGreaterThan(0); + +// The mock function was called at least once with the specified args +expect(mockFunc.mock.calls).toContain([arg1, arg2]); + +// The last call to the mock function was called with the specified args +expect(mockFunc.mock.calls[mockFunc.mock.calls.length - 1]).toEqual([ + arg1, + arg2, +]); + +// The first arg of the last call to the mock function was `42` +// (note that there is no sugar helper for this specific of an assertion) +expect(mockFunc.mock.calls[mockFunc.mock.calls.length - 1][0]).toBe(42); + +// A snapshot will check that a mock was invoked the same number of times, +// in the same order, with the same arguments. It will also assert on the name. +expect(mockFunc.mock.calls).toEqual([[arg1, arg2]]); +expect(mockFunc.mock.getMockName()).toBe('a mock name'); +``` + +For a complete list of matchers, check out the [reference docs](ExpectAPI.md). diff --git a/website/versioned_docs/version-22.4/MoreResources.md b/website/versioned_docs/version-22.4/MoreResources.md new file mode 100644 index 000000000000..860f3ba64458 --- /dev/null +++ b/website/versioned_docs/version-22.4/MoreResources.md @@ -0,0 +1,39 @@ +--- +id: version-22.4-more-resources +title: More Resources +original_id: more-resources +--- + +By now you should have a good idea of how Jest can make it easy to test your +applications. If you're interested in learning more, here's some related stuff +you might want to check out. + +### Browse the docs + +* Learn about [Snapshot Testing](SnapshotTesting.md), + [Mock Functions](MockFunctions.md), and more in our in-depth guides. +* Migrate your existing tests to Jest by following our + [migration guide](MigrationGuide.md). +* Learn how to [configure Jest](Configuration.md). +* Look at the full [API Reference](GlobalAPI.md). +* [Troubleshoot](Troubleshooting.md) problems with Jest. + +### Learn by example + +You will find a number of example test cases in the +[`examples`](https://github.com/facebook/jest/tree/master/examples) folder on +GitHub. You can also learn from the excellent tests used by the +[React](https://github.com/facebook/react/tree/master/packages/react/src/__tests__), +[Relay](https://github.com/facebook/relay/tree/master/packages/react-relay/modern/__tests__), +and +[React Native](https://github.com/facebook/react-native/tree/master/Libraries/Animated/src/__tests__) +projects. + +### Join the community + +Ask questions and find answers from other Jest users like you. +[Reactiflux](http://www.reactiflux.com/) is a Discord chat where a lot of Jest +discussion happens. Check out the [#jest](https://discord.gg/MWRhKCj) channel. + +Follow the [Jest Twitter account](https://twitter.com/fbjest) and +[blog](/jest/blog/) to find out what's happening in the world of Jest. diff --git a/website/versioned_docs/version-22.4/Puppeteer.md b/website/versioned_docs/version-22.4/Puppeteer.md new file mode 100644 index 000000000000..75ec05934efe --- /dev/null +++ b/website/versioned_docs/version-22.4/Puppeteer.md @@ -0,0 +1,124 @@ +--- +id: version-22.4-puppeteer +title: Using with puppeteer +original_id: puppeteer +--- + +With the [Global Setup/Teardown](Configuration.md#globalsetup-string) and +[Async Test Environment](Configuration.md#testenvironment-string) APIs, Jest can +work smoothly with [puppeteer](https://github.com/GoogleChrome/puppeteer). + +## Use Puppeteer Preset + +[Jest Puppeteer Preset](https://github.com/smooth-code/jest-puppeteer) provides +all required configuration to run your tests using Puppeteer. + +1. First install `jest-puppeteer-preset` + +``` +yarn add --dev jest-puppeteer-preset +``` + +2. Specify preset in your Jest configuration: + +```json +{ + "preset": "jest-puppeteer-preset" +} +``` + +See [documentation](https://github.com/smooth-code/jest-puppeteer). + +## Custom example + +The basic idea is to: + +1. launch & file the websocket endpoint of puppeteer with Global Setup +2. connect to puppeteer from each Test Environment +3. close puppeteer with Global Teardown + +Here's an example of the GlobalSetup script + +```js +// setup.js +module.exports = async function() { + const browser = await puppeteer.launch(); + // store the browser instance so we can teardown it later + global.__BROWSER__ = browser; + + // file the wsEndpoint for TestEnvironments + mkdirp.sync(DIR); + fs.writeFileSync(path.join(DIR, 'wsEndpoint'), browser.wsEndpoint()); +}; +``` + +Then we need a custom Test Environment for puppeteer + +```js +// puppeteer_environment.js +class PuppeteerEnvironment extends NodeEnvironment { + constructor(config) { + super(config); + } + + async setup() { + await super.setup(); + // get the wsEndpoint + const wsEndpoint = fs.readFileSync(path.join(DIR, 'wsEndpoint'), 'utf8'); + if (!wsEndpoint) { + throw new Error('wsEndpoint not found'); + } + + // connect to puppeteer + this.global.__BROWSER__ = await puppeteer.connect({ + browserWSEndpoint: wsEndpoint, + }); + } + + async teardown() { + await super.teardown(); + } + + runScript(script) { + return super.runScript(script); + } +} +``` + +Finally we can close the puppeteer instance and clean-up the file + +```js +// teardown.js +module.exports = async function() { + // close the browser instance + await global.__BROWSER__.close(); + + // clean-up the wsEndpoint file + rimraf.sync(DIR); +}; +``` + +With all the things set up, we can now write our tests like this: + +```js +// test.js +describe( + '/ (Home Page)', + () => { + let page; + beforeAll(async () => { + page = await global.__BROWSER__.newPage(); + await page.goto('https://google.com'); + }, timeout); + + it('should load without error', async () => { + const text = await page.evaluate(() => document.body.textContent); + expect(text).toContain('google'); + }); + }, + timeout, +); +``` + +Here's the code of +[full working example](https://github.com/xfumihiro/jest-puppeteer-example). diff --git a/website/versioned_docs/version-22.4/TestingFrameworks.md b/website/versioned_docs/version-22.4/TestingFrameworks.md new file mode 100644 index 000000000000..a1104690a19b --- /dev/null +++ b/website/versioned_docs/version-22.4/TestingFrameworks.md @@ -0,0 +1,38 @@ +--- +id: version-22.4-testing-frameworks +title: Testing Web Frameworks +original_id: testing-frameworks +--- + +Although Jest may be considered a React-specific test runner, in fact it is a +universal testing platform, with the ability to adapt to any JavaScript library +or framework. In this section we'd like to link to community posts and articles +about integrating Jest into other popular JS libraries. + +## Vue.js + +* [Testing Vue.js components with Jest](https://alexjoverm.github.io/series/Unit-Testing-Vue-js-Components-with-the-Official-Vue-Testing-Tools-and-Jest/) + by Alex Jover Morales ([@alexjoverm](https://twitter.com/alexjoverm)) +* [Jest for all: Episode 1 — Vue.js](https://medium.com/@kentaromiura_the_js_guy/jest-for-all-episode-1-vue-js-d616bccbe186#.d573vrce2) + by Cristian Carlesso ([@kentaromiura](https://twitter.com/kentaromiura)) + +## AngularJS + +* [Testing an AngularJS app with Jest](https://medium.com/aya-experience/testing-an-angularjs-app-with-jest-3029a613251) + by Matthieu Lux ([@Swiip](https://twitter.com/Swiip)) +* [Running AngularJS Tests with Jest](https://engineering.talentpair.com/running-angularjs-tests-with-jest-49d0cc9c6d26) + by Ben Brandt ([@benjaminbrandt](https://twitter.com/benjaminbrandt)) + +## Angular + +* [Testing Angular faster with Jest](https://www.xfive.co/blog/testing-angular-faster-jest/) + by Michał Pierzchała ([@thymikee](https://twitter.com/thymikee)) + +## MobX + +* [How to Test React and MobX with Jest](https://semaphoreci.com/community/tutorials/how-to-test-react-and-mobx-with-jest) + by Will Stern ([@willsterndev](https://twitter.com/willsterndev)) + +## Redux + +* [Writing Tests](https://redux.js.org/recipes/writing-tests) by Redux docs diff --git a/website/versioned_docs/version-22.4/Troubleshooting.md b/website/versioned_docs/version-22.4/Troubleshooting.md new file mode 100644 index 000000000000..4b793d23f66d --- /dev/null +++ b/website/versioned_docs/version-22.4/Troubleshooting.md @@ -0,0 +1,322 @@ +--- +id: version-22.4-troubleshooting +title: Troubleshooting +original_id: troubleshooting +--- + +Uh oh, something went wrong? Use this guide to resolve issues with Jest. + +### Tests are Failing and You Don't Know Why + +Try using the debugging support built into Node. + +Place a `debugger;` statement in any of your tests, and then, in your project's +directory, run: + +```bash +node --inspect-brk node_modules/.bin/jest --runInBand [any other arguments here] +or on Windows +node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand [any other arguments here] +``` + +This will run Jest in a Node process that an external debugger can connect to. +Note that the process will pause until the debugger has connected to it. + +To debug in Google Chrome (or any Chromium-based browser), simply open your +browser and go to `chrome://inspect` and click on "Open Dedicated DevTools for +Node", which will give you a list of available node instances you can connect +to. Simply click on the address displayed in the terminal (usually something +like `localhost:9229`) after running the above command, and you will be able to +debug Jest using Chrome's DevTools. + +The Chrome Developer Tools will be displayed, and a breakpoint will be set at +the first line of the Jest CLI script (this is done simply to give you time to +open the developer tools and to prevent Jest from executing before you have time +to do so). Click the button that looks like a "play" button in the upper right +hand side of the screen to continue execution. When Jest executes the test that +contains the `debugger` statement, execution will pause and you can examine the +current scope and call stack. + +> Note: the `--runInBand` cli option makes sure Jest runs test in the same +> process rather than spawning processes for individual tests. Normally Jest +> parallelizes test runs across processes but it is hard to debug many processes +> at the same time. + +### Debugging in VS Code + +There are multiple ways to debug Jest tests with +[Visual Studio Code's](https://code.visualstudio.com) built in +[debugger](https://code.visualstudio.com/docs/nodejs/nodejs-debugging). + +To attach the built-in debugger, run your tests as aforementioned: + +```bash +node --inspect-brk node_modules/.bin/jest --runInBand [any other arguments here] +or on Windows +node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand [any other arguments here] +``` + +Then attach VS Code's debugger using the following `launch.json` config: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "attach", + "name": "Attach", + "port": 9229 + } + ] +} +``` + +To automatically launch and attach to a process running your tests, use the +following configuration: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Jest Tests", + "type": "node", + "request": "launch", + "runtimeArgs": [ + "--inspect-brk", + "${workspaceRoot}/node_modules/.bin/jest", + "--runInBand" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} +``` + +or the following for Windows: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Jest Tests", + "type": "node", + "request": "launch", + "runtimeArgs": [ + "--inspect-brk", + "${workspaceRoot}/node_modules/jest/bin/jest.js", + "--runInBand" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} +``` + +If you are using Facebook's +[`create-react-app`](https://github.com/facebookincubator/create-react-app), you +can debug your Jest tests with the following configuration: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug CRA Tests", + "type": "node", + "request": "launch", + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts", + "args": ["test", "--runInBand", "--no-cache", "--env=jsdom"], + "cwd": "${workspaceRoot}", + "protocol": "inspector", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} +``` + +More information on Node debugging can be found +[here](https://nodejs.org/api/debugger.html). + +### Debugging in WebStorm + +The easiest way to debug Jest tests in +[WebStorm](https://www.jetbrains.com/webstorm/) is using +`Jest run/debug configuration`. It will launch tests and automatically attach +debugger. + +In the WebStorm menu `Run` select `Edit Configurations...`. Then click `+` and +select `Jest`. Optionally specify the Jest configuration file, additional +options, and environment variables. Save the configuration, put the breakpoints +in the code, then click the green debug icon to start debugging. + +If you are using Facebook's +[`create-react-app`](https://github.com/facebookincubator/create-react-app), in +the Jest run/debug configuration specify the path to the `react-scripts` package +in the Jest package field and add `--env=jsdom` to the Jest options field. + +### Caching Issues + +The transform script was changed or babel was updated and the changes aren't +being recognized by Jest? + +Retry with [`--no-cache`](CLI.md#cache). Jest caches transformed module files to +speed up test execution. If you are using your own custom transformer, consider +adding a `getCacheKey` function to it: +[getCacheKey in Relay](https://github.com/facebook/relay/blob/58cf36c73769690f0bbf90562707eadb062b029d/scripts/jest/preprocessor.js#L56-L61). + +### Unresolved Promises + +If a promise doesn't resolve at all, this error might be thrown: + +```bash +- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.` +``` + +Most commonly this is being caused by conflicting Promise implementations. +Consider replacing the global promise implementation with your own, for example +`global.Promise = require.requireActual('promise');` and/or consolidate the used +Promise libraries to a single one. + +If your test is long running, you may want to consider to increase the timeout +by calling `jest.setTimeout` + +```js +jest.setTimeout(10000); // 10 second timeout +``` + +### Watchman Issues + +Try running Jest with [`--no-watchman`](CLI.md#watchman) or set the `watchman` +configuration option to `false`. + +Also see +[watchman troubleshooting](https://facebook.github.io/watchman/docs/troubleshooting.html). + +### Tests are Extremely Slow on Docker and/or Continuous Integration (CI) server. + +While Jest is most of the time extremely fast on modern multi-core computers +with fast SSDs, it may be slow on certain setups as our users +[have](https://github.com/facebook/jest/issues/1395) +[discovered](https://github.com/facebook/jest/issues/1524#issuecomment-260246008). + +Based on the +[findings](https://github.com/facebook/jest/issues/1524#issuecomment-262366820), +one way to mitigate this issue and improve the speed by up to 50% is to run +tests sequentially. + +In order to do this you can run tests in the same thread using +[`--runInBand`](CLI.md#runinband): + +```bash +# Using Jest CLI +jest --runInBand + +# Using yarn test (e.g. with create-react-app) +yarn test --runInBand +``` + +Another alternative to expediting test execution time on Continuous Integration +Servers such as Travis-CI is to set the max worker pool to ~_4_. Specifically on +Travis-CI, this can reduce test execution time in half. Note: The Travis CI +_free_ plan available for open source projects only includes 2 CPU cores. + +```bash +# Using Jest CLI +jest --maxWorkers=4 + +# Using yarn test (e.g. with create-react-app) +yarn test --maxWorkers=4 +``` + +### Tests are slow when leveraging automocking + +Whether via [`automock: true`](configuration.html#automock-boolean) in config or +lots of +[`jest.mock('my-module')`](jest-object.html#jestmockmodulename-factory-options) +calls in tests, automocking has a performance cost that can add up in large +projects. The more dependencies a module has, the more work Jest has to do to +mock it. Something that can offset this performance cost significantly is adding +a code transformer that moves `import` or `require` calls from the top of a +module, where they are always executed, down into the body of the module, where +they are usually not executed. This can lower the number of modules Jest has to +load when running your tests by a considerable amount. + +To transform `import` statements, there is +[babel-plugin-transform-inline-imports-commonjs](https://github.com/zertosh/babel-plugin-transform-inline-imports-commonjs), +and to transform `require` statements, there is +[Facebook's `inline-requires` babel plugin](https://github.com/facebook/fbjs/blob/master/packages/babel-preset-fbjs/plugins/inline-requires.js), +which is part of the `babel-preset-fbjs` package. + +### I'm using npm3 and my node_modules aren't properly loading. + +Upgrade `jest-cli` to `0.9.0` or above. + +### I'm using babel and my unmocked imports aren't working? + +Upgrade `jest-cli` to `0.9.0` or above. + +Explanation: + +```js +jest.dontMock('foo'); + +import foo from './foo'; +``` + +In ES6, import statements get hoisted before all other + +```js +const foo = require('foo'); +jest.dontMock('foo'); // Oops! +``` + +In Jest 0.9.0, a new API `jest.unmock` was introduced. Together with a plugin +for babel, this will now work properly when using `babel-jest`: + +```js +jest.unmock('./foo'); // Use unmock! + +import foo from './foo'; + +// foo is not mocked! +``` + +See the [Getting Started]GettingStarted.md#using-babel) guide on how to enable +babel support. + +### I upgraded to Jest 0.9.0 and my tests are now failing? + +Jest is now using Jasmine 2 by default. It should be easy to upgrade using the +Jasmine [upgrade guide](http://jasmine.github.io/2.0/introduction.html). + +If you would like to continue using Jasmine 1, set the `testRunner` config +option to `jasmine1` or pass `--testRunner=jasmine1` as a command line option. + +### Compatibility issues + +Jest takes advantage of new features added to Node 6. We recommend that you +upgrade to the latest stable release of Node. The minimum supported version is +`v6.0.0`. Versions `0.x.x` and `4.x.x` are not supported because the `jsdom` +version used in Jest doesn't support Node 4. However, if you need to run Jest on +Node 4, you can use the `testEnvironment` config to use a +[custom environment](https://facebook.github.io/jest/docs/en/configuration.html#testenvironment-string) +that supports Node 4, such as +[`jest-environment-node`](https://yarnpkg.com/en/package/jest-environment-node). + +### `coveragePathIgnorePatterns` seems to not have any effect. + +Make sure you are not using the `babel-plugin-istanbul` plugin. Jest wraps +Istanbul, and therefore also tells Istanbul what files to instrument with +coverage collection. When using `babel-plugin-istanbul`, every file that is +processed by Babel will have coverage collection code, hence it is not being +ignored by `coveragePathIgnorePatterns`. + +### Still unresolved? + +See [Help](/jest/help.html). diff --git a/website/versioned_docs/version-22.4/TutorialReact.md b/website/versioned_docs/version-22.4/TutorialReact.md new file mode 100644 index 000000000000..5b8f4ace8171 --- /dev/null +++ b/website/versioned_docs/version-22.4/TutorialReact.md @@ -0,0 +1,337 @@ +--- +id: version-22.4-tutorial-react +title: Testing React Apps +original_id: tutorial-react +--- + +At Facebook, we use Jest to test [React](http://facebook.github.io/react/) +applications. + +## Setup + +### Setup with Create React App + +If you are just getting started with React, we recommend using +[Create React App](https://github.com/facebookincubator/create-react-app). It is +ready to use and +[ships with Jest](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#running-tests)! +You don't need to do any extra steps for setup, and can head straight to the +next section. + +### Setup without Create React App + +If you have an existing application you'll need to install a few packages to +make everything work well together. We are using the `babel-jest` package and +the `react` babel preset to transform our code inside of the test environment. +Also see [using babel](GettingStarted.md#using-babel). + +Run + +```bash +yarn add --dev jest babel-jest babel-preset-env babel-preset-react react-test-renderer +``` + +Your `package.json` should look something like this (where `` +is the actual latest version number for the package). Please add the scripts and +jest configuration entries: + +```json +// package.json + "dependencies": { + "react": "", + "react-dom": "" + }, + "devDependencies": { + "babel-jest": "", + "babel-preset-env": "", + "babel-preset-react": "", + "jest": "", + "react-test-renderer": "" + }, + "scripts": { + "test": "jest" + } +``` + +```json +// .babelrc +{ + "presets": ["env", "react"] +} +``` + +**And you're good to go!** + +### Snapshot Testing + +Let's create a [snapshot test](SnapshotTesting.md) for a Link component that +renders hyperlinks: + +```javascript +// Link.react.js +import React from 'react'; + +const STATUS = { + HOVERED: 'hovered', + NORMAL: 'normal', +}; + +export default class Link extends React.Component { + constructor(props) { + super(props); + + this._onMouseEnter = this._onMouseEnter.bind(this); + this._onMouseLeave = this._onMouseLeave.bind(this); + + this.state = { + class: STATUS.NORMAL, + }; + } + + _onMouseEnter() { + this.setState({class: STATUS.HOVERED}); + } + + _onMouseLeave() { + this.setState({class: STATUS.NORMAL}); + } + + render() { + return ( + + {this.props.children} + + ); + } +} +``` + +Now let's use React's test renderer and Jest's snapshot feature to interact with +the component and capture the rendered output and create a snapshot file: + +```javascript +// Link.react.test.js +import React from 'react'; +import Link from '../Link.react'; +import renderer from 'react-test-renderer'; + +test('Link changes the class when hovered', () => { + const component = renderer.create( + Facebook, + ); + let tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + + // manually trigger the callback + tree.props.onMouseEnter(); + // re-rendering + tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + + // manually trigger the callback + tree.props.onMouseLeave(); + // re-rendering + tree = component.toJSON(); + expect(tree).toMatchSnapshot(); +}); +``` + +When you run `yarn test` or `jest`, this will produce an output file like this: + +```javascript +// __tests__/__snapshots__/Link.react.test.js.snap +exports[`Link changes the class when hovered 1`] = ` + + Facebook + +`; + +exports[`Link changes the class when hovered 2`] = ` + + Facebook + +`; + +exports[`Link changes the class when hovered 3`] = ` + + Facebook + +`; +``` + +The next time you run the tests, the rendered output will be compared to the +previously created snapshot. The snapshot should be committed along code +changes. When a snapshot test fails, you need to inspect whether it is an +intended or unintended change. If the change is expected you can invoke Jest +with `jest -u` to overwrite the existing snapshot. + +The code for this example is available at +[examples/snapshot](https://github.com/facebook/jest/tree/master/examples/snapshot). + +#### Snapshot Testing with Mocks, Enzyme and React 16 + +There's a caveat around snapshot testing when using Enzyme and React 16+. If you +mock out a module using the following style: + +```js +jest.mock('../SomeDirectory/SomeComponent', () => 'SomeComponent'); +``` + +Then you will see warnings in the console: + +```bash +Warning: is using uppercase HTML. Always use lowercase HTML tags in React. + +# Or: +Warning: The tag is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter. +``` + +React 16 triggers these warnings due to how it checks element types, and the +mocked module fails these checks. Your options are: + +1. Render as text. This way you won't see the props passed to the mock + component in the snapshot, but it's straightforward: + ```js + jest.mock('./SomeComponent', () => () => 'SomeComponent'); + ``` +2. Render as a custom element. DOM "custom elements" aren't checked for + anything and shouldn't fire warnings. They are lowercase and have a dash in + the name. + ```js + jest.mock('./Widget', () => 'mock-widget'); + ``` +3. Use `react-test-renderer`. The test renderer doesn't care about element + types and will happily accept e.g. `SomeComponent`. You could check + snapshots using the test renderer, and check component behavior separately + using Enzyme. + +### DOM Testing + +If you'd like to assert, and manipulate your rendered components you can use +[Enzyme](http://airbnb.io/enzyme/) or React's +[TestUtils](http://facebook.github.io/react/docs/test-utils.html). We use Enzyme +for this example. + +You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React +version below 15.5.0, you will also need to install `react-addons-test-utils`. + +Let's implement a simple checkbox which swaps between two labels: + +```javascript +// CheckboxWithLabel.js + +import React from 'react'; + +export default class CheckboxWithLabel extends React.Component { + constructor(props) { + super(props); + this.state = {isChecked: false}; + + // bind manually because React class components don't auto-bind + // http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding + this.onChange = this.onChange.bind(this); + } + + onChange() { + this.setState({isChecked: !this.state.isChecked}); + } + + render() { + return ( + + ); + } +} +``` + +We use Enzyme's +[shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this +example. + +```javascript +// __tests__/CheckboxWithLabel-test.js + +import React from 'react'; +import {shallow} from 'enzyme'; +import CheckboxWithLabel from '../CheckboxWithLabel'; + +test('CheckboxWithLabel changes the text after click', () => { + // Render a checkbox with label in the document + const checkbox = shallow(); + + expect(checkbox.text()).toEqual('Off'); + + checkbox.find('input').simulate('change'); + + expect(checkbox.text()).toEqual('On'); +}); +``` + +The code for this example is available at +[examples/enzyme](https://github.com/facebook/jest/tree/master/examples/enzyme). + +### Custom transformers + +If you need more advanced functionality, you can also build your own +transformer. Instead of using babel-jest, here is an example of using babel: + +```javascript +// custom-transformer.js +'use strict'; + +const babel = require('babel-core'); +const jestPreset = require('babel-preset-jest'); + +module.exports = { + process(src, filename) { + if (babel.util.canCompile(filename)) { + return babel.transform(src, { + filename, + presets: [jestPreset], + }); + } + return src; + }, +}; +``` + +Don't forget to install the `babel-core` and `babel-preset-jest` packages for +this example to work. + +To make this work with Jest you need to update your Jest configuration with +this: `"transform": {"\\.js$": "path/to/custom-transformer.js"}`. + +If you'd like to build a transformer with babel support, you can also use +babel-jest to compose one and pass in your custom configuration options: + +```javascript +const babelJest = require('babel-jest'); + +module.exports = babelJest.createTransformer({ + presets: ['my-custom-preset'], +}); +``` diff --git a/website/versioned_docs/version-22.4/TutorialReactNative.md b/website/versioned_docs/version-22.4/TutorialReactNative.md new file mode 100644 index 000000000000..eabb44d84163 --- /dev/null +++ b/website/versioned_docs/version-22.4/TutorialReactNative.md @@ -0,0 +1,273 @@ +--- +id: version-22.4-tutorial-react-native +title: Testing React Native Apps +original_id: tutorial-react-native +--- + +At Facebook, we use Jest to test +[React Native](http://facebook.github.io/react-native/) applications. + +Get a deeper insight into testing a working React Native app example by reading +the following series: +[Part 1: Jest – Snapshot come into play](https://blog.callstack.io/unit-testing-react-native-with-the-new-jest-i-snapshots-come-into-play-68ba19b1b9fe#.12zbnbgwc) +and +[Part 2: Jest – Redux Snapshots for your Actions and Reducers](https://blog.callstack.io/unit-testing-react-native-with-the-new-jest-ii-redux-snapshots-for-your-actions-and-reducers-8559f6f8050b). + +## Setup + +Starting from react-native version 0.38, a Jest setup is included by default +when running `react-native init`. The following configuration should be +automatically added to your package.json file: + +```json +// package.json + "scripts": { + "test": "jest" + }, + "jest": { + "preset": "react-native" + } +``` + +_Note: If you are upgrading your react-native application and previously used +the `jest-react-native` preset, remove the dependency from your `package.json` +file and change the preset to `react-native` instead._ + +Simply run `yarn test` to run tests with Jest. + +## Snapshot Test + +Let's create a [snapshot test](SnapshotTesting.md) for a small intro component +with a few views and text components and some styles: + +```javascript +// Intro.js +import React, {Component} from 'react'; +import {StyleSheet, Text, View} from 'react-native'; + +const styles = StyleSheet.create({ + container: { + alignItems: 'center', + backgroundColor: '#F5FCFF', + flex: 1, + justifyContent: 'center', + }, + instructions: { + color: '#333333', + marginBottom: 5, + textAlign: 'center', + }, + welcome: { + fontSize: 20, + margin: 10, + textAlign: 'center', + }, +}); + +export default class Intro extends Component { + render() { + return ( + + Welcome to React Native! + + This is a React Native snapshot test. + + + ); + } +} +``` + +Now let's use React's test renderer and Jest's snapshot feature to interact with +the component and capture the rendered output and create a snapshot file: + +```javascript +// __tests__/Intro-test.js +import React from 'react'; +import Intro from '../Intro'; + +import renderer from 'react-test-renderer'; + +test('renders correctly', () => { + const tree = renderer.create().toJSON(); + expect(tree).toMatchSnapshot(); +}); +``` + +When you run `yarn test` or `jest`, this will produce an output file like this: + +```javascript +// __tests__/__snapshots__/Intro-test.js.snap +exports[`Intro renders correctly 1`] = ` + + + Welcome to React Native! + + + This is a React Native snapshot test. + + +`; +``` + +The next time you run the tests, the rendered output will be compared to the +previously created snapshot. The snapshot should be committed along code +changes. When a snapshot test fails, you need to inspect whether it is an +intended or unintended change. If the change is expected you can invoke Jest +with `jest -u` to overwrite the existing snapshot. + +The code for this example is available at +[examples/react-native](https://github.com/facebook/jest/tree/master/examples/react-native). + +## Preset configuration + +The preset sets up the environment and is very opinionated and based on what we +found to be useful at Facebook. All of the configuration options can be +overwritten just as they can be customized when no preset is used. + +### Environment + +`react-native` ships with a Jest preset, so the `jest.preset` field of your +`package.json` should point to `react-native`. The preset is a node environment +that mimics the environment of a React Native app. Because it doesn't load any +DOM or browser APIs, it greatly improves Jest's startup time. + +### transformIgnorePatterns customization + +The +[`transformIgnorePatterns`](configuration.html#transformignorepatterns-array-string) +option can be used to whitelist or blacklist files from being transformed with +babel. Many react-native npm modules unfortunately don't pre-compile their +source code before publishing. + +By default the jest-react-native preset only processes the project's own source +files and react-native. If you have npm dependencies that have to be transformed +you can customize this configuration option by whitelisting modules other than +react-native: + +```json +"transformIgnorePatterns": [ + "node_modules/(?!(react-native|my-project|react-native-button)/)" +] +``` + +### setupFiles + +If you'd like to provide additional configuration for every test file, the +[`setupFiles` configuration option](configuration.html#setupfiles-array) can be +used to specify setup scripts. + +### moduleNameMapper + +The +[`moduleNameMapper`](configuration.html#modulenamemapper-object-string-string) +can be used to map a module path to a different module. By default the preset +maps all images to an image stub module but if a module cannot be found this +configuration option can help: + +```json +"moduleNameMapper": { + "my-module.js": "/path/to/my-module.js" +} +``` + +## Tips + +### Mock native modules using jest.mock + +The Jest preset built into `react-native` comes with a few default mocks that +are applied on a react-native repository. However some react-native components +or third party components rely on native code to be rendered. In such cases, +Jest's manual mocking system can help to mock out the underlying implementation. + +For example, if your code depends on a third party native video component called +`react-native-video` you might want to stub it out with a manual mock like this: + +```js +jest.mock('react-native-video', () => 'Video'); +``` + +This will render the component as `