From f5b5d81922b29eee9f524633a5fb2711002cd8c6 Mon Sep 17 00:00:00 2001 From: rickhanlonii Date: Wed, 4 Jul 2018 15:25:08 -0400 Subject: [PATCH 1/3] Add docs for 23.1, 23.2, and 23.3 --- website/versioned_docs/version-23.1/CLI.md | 286 ++++ .../version-23.1/Configuration.md | 902 +++++++++++++ .../versioned_docs/version-23.1/ExpectAPI.md | 1137 ++++++++++++++++ .../version-23.1/JestObjectAPI.md | 476 +++++++ .../version-23.1/MockFunctionAPI.md | 310 +++++ .../version-23.1/WatchPlugins.md | 140 ++ website/versioned_docs/version-23.2/CLI.md | 290 +++++ .../version-23.2/Configuration.md | 904 +++++++++++++ .../versioned_docs/version-23.2/ExpectAPI.md | 1137 ++++++++++++++++ .../version-23.2/GettingStarted.md | 139 ++ .../versioned_docs/version-23.2/GlobalAPI.md | 652 ++++++++++ .../version-23.2/JestObjectAPI.md | 476 +++++++ .../version-23.2/MockFunctions.md | 287 ++++ .../versioned_docs/version-23.2/MongoDB.md | 141 ++ .../versioned_docs/version-23.2/Puppeteer.md | 121 ++ .../version-23.2/WatchPlugins.md | 150 +++ website/versioned_docs/version-23.3/CLI.md | 296 +++++ .../version-23.3/Configuration.md | 910 +++++++++++++ .../versioned_docs/version-23.3/ExpectAPI.md | 1149 +++++++++++++++++ .../version-23.3/JestObjectAPI.md | 508 ++++++++ .../version-23.3/SnapshotTesting.md | 293 +++++ .../version-23.3/WatchPlugins.md | 183 +++ website/versions.json | 3 + 23 files changed, 10890 insertions(+) create mode 100644 website/versioned_docs/version-23.1/CLI.md create mode 100644 website/versioned_docs/version-23.1/Configuration.md create mode 100644 website/versioned_docs/version-23.1/ExpectAPI.md create mode 100644 website/versioned_docs/version-23.1/JestObjectAPI.md create mode 100644 website/versioned_docs/version-23.1/MockFunctionAPI.md create mode 100644 website/versioned_docs/version-23.1/WatchPlugins.md create mode 100644 website/versioned_docs/version-23.2/CLI.md create mode 100644 website/versioned_docs/version-23.2/Configuration.md create mode 100644 website/versioned_docs/version-23.2/ExpectAPI.md create mode 100644 website/versioned_docs/version-23.2/GettingStarted.md create mode 100644 website/versioned_docs/version-23.2/GlobalAPI.md create mode 100644 website/versioned_docs/version-23.2/JestObjectAPI.md create mode 100644 website/versioned_docs/version-23.2/MockFunctions.md create mode 100644 website/versioned_docs/version-23.2/MongoDB.md create mode 100644 website/versioned_docs/version-23.2/Puppeteer.md create mode 100644 website/versioned_docs/version-23.2/WatchPlugins.md create mode 100644 website/versioned_docs/version-23.3/CLI.md create mode 100644 website/versioned_docs/version-23.3/Configuration.md create mode 100644 website/versioned_docs/version-23.3/ExpectAPI.md create mode 100644 website/versioned_docs/version-23.3/JestObjectAPI.md create mode 100644 website/versioned_docs/version-23.3/SnapshotTesting.md create mode 100644 website/versioned_docs/version-23.3/WatchPlugins.md diff --git a/website/versioned_docs/version-23.1/CLI.md b/website/versioned_docs/version-23.1/CLI.md new file mode 100644 index 000000000000..a5efc3ee97c6 --- /dev/null +++ b/website/versioned_docs/version-23.1/CLI.md @@ -0,0 +1,286 @@ +--- +id: version-23.1-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` + +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` + +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=` + +A glob pattern 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. + +### `--detectOpenHandles` + +Attempt to collect and print open handles preventing Jest from exiting cleanly. Use this in cases where you need to use `--forceExit` in order for Jest to exit to potentially track down the reason. Implemented using [`async_hooks`](https://nodejs.org/api/async_hooks.html), so it only works in Node 8 and newer. + +### `--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`. + +### `--errorOnDeprecated` + +Make calling deprecated APIs throw helpful error messages. Useful for easing the upgrade process. + +### `--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. Can be used together with `--coverage` to include a test coverage for the source files, no duplicate `--collectCoverageFrom` arguments needed. + +### `--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. You can use `--detectOpenHandles` to help track it down._ + +### `--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 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`. + +_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ + +### `--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-23.1/Configuration.md b/website/versioned_docs/version-23.1/Configuration.md new file mode 100644 index 000000000000..8557dc3aedcd --- /dev/null +++ b/website/versioned_docs/version-23.1/Configuration.md @@ -0,0 +1,902 @@ +--- +id: version-23.1-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. + +### Defaults + +You can retrieve Jest's default options to expand them if needed: + +```js +// jest.config.js +const {defaults} = require('jest-config'); +module.exports = { + // ... + moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'], + // ... +}; +``` + + + +--- + +## 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. + +### `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. + +### `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/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib) 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` or `jest-preset.js` module at its top level. + +Presets may also be relative filesystem paths. + +```json +{ + "preset": "./node_modules/foo-bar/jest-preset.js" +} +``` + +### `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._ + +### `reporters` [array] + +Default: `undefined` + +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` + +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] + +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 +``` + +If you need to restrict your test-runner to only run in serial rather then being executed in parallel your class should have the property `isSerial` to be set as `true`. + +### `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. + +### `errorOnDeprecated` [boolean] + +Default: `false` + +Make calling deprecated APIs throw helpful error messages. Useful for easing the upgrade process. + +### `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. + +By adding a `@jest-environment` docblock at the top of the file, you can specify another environment to be used for all tests in that file: + +```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. + +_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] + +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] + +(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, + "openHandles": Array, + "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: `[]` + +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-23.1/ExpectAPI.md b/website/versioned_docs/version-23.1/ExpectAPI.md new file mode 100644 index 000000000000..6575f1280195 --- /dev/null +++ b/website/versioned_docs/version-23.1/ExpectAPI.md @@ -0,0 +1,1137 @@ +--- +id: version-23.1-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); + expect({apples: 6, bananas: 3}).toEqual({ + apples: expect.toBeDivisibleBy(2), + bananas: expect.not.toBeDivisibleBy(2), + }); +}); +``` + +`expect.extends` also supports async matchers. Async matchers return a Promise so you will need to await the returned value. Let's use an example matcher to illustrate the usage of them. We are going to implement a very similar matcher than `toBeDivisibleBy`, only difference is that the divisible number is going to be pulled from an external source. + +```js +expect.extend({ + async toBeDivisibleByExternalValue(received) { + const externalValue = await getExternalValueFromRemoteSource(); + const pass = received % externalValue == 0; + if (pass) { + return { + message: () => + `expected ${received} not to be divisible by ${externalValue}`, + pass: true, + }; + } else { + return { + message: () => + `expected ${received} to be divisible by ${externalValue}`, + pass: false, + }; + } + }, +}); + +test('is divisible by external value', async () => { + await expect(100).toBeDivisibleByExternalValue(); + await expect(101).not.toBeDivisibleByExternalValue(); +}); +``` + +Matchers should return an object (or a Promise of 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 the 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(string | regexp)` + +`expect.not.stringMatching(string | regexp)` matches the 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 the received string that contains the exact expected string. + +### `expect.stringMatching(string | regexp)` + +`expect.stringMatching(string | regexp)` matches the 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` + +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` + +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)` + +Also under the alias: `.toBeCalledTimes(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'); +}); +``` + +### `.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)` + +Also under the alias: `.nthCalledWith(nthCall, arg1, arg2, ...)` + +If you have a mock function, you can use `.toHaveBeenNthCalledWith` to test what arguments it was nth called with. For example, let's say you have a `drinkEach(drink, Array)` function that applies `f` to a bunch of flavors, and you want to ensure that when you call it, the first flavor it operates on is `'lemon'` and the second one is `'octopus'`. You can write: + +```js +test('drinkEach drinks each drink', () => { + const drink = jest.fn(); + drinkEach(drink, ['lemon', 'octopus']); + expect(drink).toHaveBeenNthCalledWith(1, 'lemon'); + expect(drink).toHaveBeenNthCalledWith(2, 'octopus'); +}); +``` + +Note: the nth argument must be positive integer starting from 1. + +### `.toHaveReturned()` + +Also under the alias: `.toReturn()` + +If you have a mock function, you can use `.toHaveReturned` to test that the mock function successfully returned (i.e., did not throw an error) at least one time. For example, let's say you have a mock `drink` that returns `true`. You can write: + +```js +test('drinks returns', () => { + const drink = jest.fn(() => true); + + drink(); + + expect(drink).toHaveReturned(); +}); +``` + +### `.toHaveReturnedTimes(number)` + +Also under the alias: `.toReturnTimes(number)` + +Use `.toHaveReturnedTimes` to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times. Any calls to the mock function that throw an error are not counted toward the number of times the function returned. + +For example, let's say you have a mock `drink` that returns `true`. You can write: + +```js +test('drink returns twice', () => { + const drink = jest.fn(() => true); + + drink(); + drink(); + + expect(drink).toHaveReturnedTimes(2); +}); +``` + +### `.toHaveReturnedWith(value)` + +Also under the alias: `.toReturnWith(value)` + +Use `.toHaveReturnedWith` to ensure that a mock function returned a specific value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns La Croix', () => { + const beverage = {name: 'La Croix'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage); + + expect(drink).toHaveReturnedWith('La Croix'); +}); +``` + +### `.toHaveLastReturnedWith(value)` + +Also under the alias: `.lastReturnedWith(value)` + +Use `.toHaveLastReturnedWith` to test the specific value that a mock function last returned. If the last call to the mock function threw an error, then this matcher will fail no matter what value you provided as the expected return value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns La Croix (Orange) last', () => { + const beverage1 = {name: 'La Croix (Lemon)'}; + const beverage2 = {name: 'La Croix (Orange)'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage1); + drink(beverage2); + + expect(drink).toHaveLastReturnedWith('La Croix (Orange)'); +}); +``` + +### `.toHaveNthReturnedWith(nthCall, value)` + +Also under the alias: `.nthReturnedWith(nthCall, value)` + +Use `.toHaveNthReturnedWith` to test the specific value that a mock function returned for the nth call. If the nth call to the mock function threw an error, then this matcher will fail no matter what value you provided as the expected return value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns expected nth calls', () => { + const beverage1 = {name: 'La Croix (Lemon)'}; + const beverage2 = {name: 'La Croix (Orange)'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage1); + drink(beverage2); + + expect(drink).toHaveNthReturnedWith(1, 'La Croix (Lemon)'); + expect(drink).toHaveNthReturnedWith(2, 'La Croix (Orange)'); +}); +``` + +Note: the nth argument must be positive integer starting from 1. + +### `.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(propertyMatchers, snapshotName)` + +This ensures that a value matches the most recent snapshot. Check out [the Snapshot Testing guide](SnapshotTesting.md) for more information. + +The optional propertyMatchers argument allows you to specify asymmetric matchers which are verified instead of the exact values. + +The last argument allows you option to specify a 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._ + +### `.toStrictEqual(value)` + +Use `.toStrictEqual` to test that objects have the same types as well as structure. + +Differences from `.toEqual`: + +* Keys with `undefined` properties are checked. e.g. `{a: undefined, b: 2}` does not match `{b: 2}` when using `.toStrictEqual`. +* Object types are checked to be equal. e.g. A class instance with fields `a` and `b` will not equal a literal object with fields `a` and `b`. + +```js +class LaCroix { + constructor(flavor) { + this.flavor = flavor; + } +} + +describe('the La Croix cans on my desk', () => { + test('are not semantically the same', () => { + expect(new LaCroix('lemon')).toEqual({flavor: 'lemon'}); + expect(new LaCroix('lemon')).not.toStrictEqual({flavor: 'lemon'}); + }); +}); +``` + +### `.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 that should be contained in the error message, a class for the error, or a regex that should match the error message. 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 that the error message says "yuck" somewhere: these are equivalent + expect(drinkOctopus).toThrowError(/yuck/); + expect(drinkOctopus).toThrowError('yuck'); + + // Test the exact error message + expect(drinkOctopus).toThrowError(/^yuck, octopus flavor$/); + + // 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-23.1/JestObjectAPI.md b/website/versioned_docs/version-23.1/JestObjectAPI.md new file mode 100644 index 000000000000..d55ae168dfc9 --- /dev/null +++ b/website/versioned_docs/version-23.1/JestObjectAPI.md @@ -0,0 +1,476 @@ +--- +id: version-23.1-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()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.resetAllMocks()` + +Resets the state of all mocks. Equivalent to calling [`.mockReset()`](MockFunctionAPI.md#mockfnmockreset) on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.restoreAllMocks()` + +Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) 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)` + +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.mockRestore(); +}); +``` + +### `jest.spyOn(object, methodName, accessType?)` + +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 = audio; +``` + +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.mockRestore(); +}); + +const audio = require('./audio'); + +test('plays audio', () => { + const spy = jest.spyOn(audio, 'volume', 'set'); // we pass 'set' + audio.volume = 100; + + expect(spy).toHaveBeenCalled(); + expect(audio.volume).toBe(100); + + spy.mockRestore(); +}); +``` diff --git a/website/versioned_docs/version-23.1/MockFunctionAPI.md b/website/versioned_docs/version-23.1/MockFunctionAPI.md new file mode 100644 index 000000000000..8f4ae9fa4472 --- /dev/null +++ b/website/versioned_docs/version-23.1/MockFunctionAPI.md @@ -0,0 +1,310 @@ +--- +id: version-23.1-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()` + +Returns the mock name string set by calling `mockFn.mockName(value)`. + +### `mockFn.mock.calls` + +An array containing the call arguments of all calls that have been made to this mock function. Each item in the array is 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.results` + +An array containing the results of all calls that have been made to this mock function. Each entry in this array is an object containing a boolean `isThrow` property, and a `value` property. `isThrow` is true if the call terminated due to a `throw`, or false if the the call returned normally. The `value` property contains the value that was thrown or returned. + +For example: A mock function `f` that has been called three times, returning `result1`, throwing an error, and then returning `result2`, would have a `mock.results` array that looks like this: + +```js +[ + { + isThrow: false, + value: 'result1', + }, + { + isThrow: true, + value: { + /* Error instance */ + }, + }, + { + isThrow: false, + value: 'result2', + }, +]; +``` + +### `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()` + +Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also removes any mocked return values or implementations. + +This is useful when you want to completely reset a _mock_ back to its initial state. (Note that resetting a _spy_ will result in a function with no return value). + +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()` + +Does everything that [`mockFn.mockReset()`](#mockfnmockreset) does, and also restores the original (non-mocked) 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)` + +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)` + +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)` + +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)` + +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)` + +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-23.1/WatchPlugins.md b/website/versioned_docs/version-23.1/WatchPlugins.md new file mode 100644 index 000000000000..c346cc04f5bd --- /dev/null +++ b/website/versioned_docs/version-23.1/WatchPlugins.md @@ -0,0 +1,140 @@ +--- +id: version-23.1-watch-plugins +title: Watch Plugins +original_id: watch-plugins +--- + +The Jest watch plugin system provides a way to hook into specific parts of Jest and to define watch mode menu prompts that execute code on key press. Combined, these features allow you to develop interactive experiences custom for your workflow. + +## Watch Plugin Interface + +```javascript +class MyWatchPlugin { + // Add hooks to Jest lifecycle events + apply(jestHooks) {} + + // Get the prompt information for interactive plugins + getUsageInfo(globalConfig) {} + + // Executed when the key from `getUsageInfo` is input + run(globalConfig, updateConfigAndRun) {} +} +``` + +## Hooking into Jest + +Custom watch plugins can add hooks to Jest events. These hooks can be added either with or without having an interactive key in the watch mode menu. + +### `apply(jestHooks)` + +Jest hooks can be attached by implementing the `apply` method. This method receives a `jestHooks` argument that allows the plugin to hook into specific parts of the lifecycle of a test run. + +```javascript +class MyWatchPlugin { + apply(jestHooks) {} +} +``` + +Below are the hooks available in Jest. + +#### `jestHooks.shouldRunTestSuite(testPath)` + +Returns a boolean (or `Promise`) for handling asynchronous operations) to specify if a test should be run or not. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.shouldRunTestSuite(testPath => { + return testPath.includes('my-keyword'); + }); + + // or a promise + jestHooks.shouldRunTestSuite(testPath => { + return Promise.resolve(testPath.includes('my-keyword')); + }); + } +} +``` + +#### `jestHooks.onTestRunComplete(results)` + +Gets called at the end of every test run. It has the test results as an argument. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.onTestRunComplete(results => { + this._hasSnapshotFailure = results.snapshot.failure; + }); + } +} +``` + +#### `jestHooks.onFileChange({projects})` + +Gets called whenever there is a change in the file system + +* `projects: Array`: Includes all the test paths that Jest is watching. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.onFileChange(({projects}) => { + this._projects = projects; + }); + } +} +``` + +## Watch Menu Integration + +Custom watch plugins can also add or override functionality to the watch menu by specifying a key/prompt pair in `getUsageInfo` method and a `run` method for the execution of the key. + +### `getUsageInfo(globalConfig)` + +To add a key to the watch menu, implement the `getUsageInfo` method, returning a key and the prompt: + +```javascript +class MyWatchPlugin { + getUsageInfo(globalConfig) { + return { + key: 's', + prompt: 'do something', + }; + } +} +``` + +This will add a line in the watch mode menu _(`› Press s to do something.`)_ + +```text +Watch Usage + › Press p to filter by a filename regex pattern. + › Press t to filter by a test name regex pattern. + › Press q to quit watch mode. + › Press s to do something. // <-- This is our plugin + › Press Enter to trigger a test run. +``` + +**Note**: If the key for your plugin already exists as a default key, your plugin will override that key. + +### `run(globalConfig, updateConfigAndRun)` + +To handle key press events from the key returned by `getUsageInfo`, you can implement the `run` method. This method returns a `Promise` that can be resolved when the plugin wants to return control to Jest. The `boolean` specifies if Jest should rerun the tests after it gets the control back. + +* `globalConfig`: A representation of Jest's current global configuration +* `updateConfigAndRun`: Allows you to trigger a test run while the interactive plugin is running. + +```javascript +class MyWatchPlugin { + run(globalConfig, updateConfigAndRun) { + // do something. + } +} +``` diff --git a/website/versioned_docs/version-23.2/CLI.md b/website/versioned_docs/version-23.2/CLI.md new file mode 100644 index 000000000000..484fd86aa0e8 --- /dev/null +++ b/website/versioned_docs/version-23.2/CLI.md @@ -0,0 +1,290 @@ +--- +id: version-23.2-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` + +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` + +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=` + +A glob pattern 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. + +### `--detectOpenHandles` + +Attempt to collect and print open handles preventing Jest from exiting cleanly. Use this in cases where you need to use `--forceExit` in order for Jest to exit to potentially track down the reason. Implemented using [`async_hooks`](https://nodejs.org/api/async_hooks.html), so it only works in Node 8 and newer. + +### `--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`. + +### `--errorOnDeprecated` + +Make calling deprecated APIs throw helpful error messages. Useful for easing the upgrade process. + +### `--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. Can be used together with `--coverage` to include a test coverage for the source files, no duplicate `--collectCoverageFrom` arguments needed. + +### `--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. You can use `--detectOpenHandles` to help track it down._ + +### `--help` + +Show the help information, similar to this page. + +### `--init` + +Generate a basic configuration file. Based on your project, Jest will ask you a few questions that will help to generate a `jest.config.js` file with a short description for each option. + +### `--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 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`. + +_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ + +### `--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-23.2/Configuration.md b/website/versioned_docs/version-23.2/Configuration.md new file mode 100644 index 000000000000..e5d4ad3bbced --- /dev/null +++ b/website/versioned_docs/version-23.2/Configuration.md @@ -0,0 +1,904 @@ +--- +id: version-23.2-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. + +### Defaults + +You can retrieve Jest's default options to expand them if needed: + +```js +// jest.config.js +const {defaults} = require('jest-config'); +module.exports = { + // ... + moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'], + // ... +}; +``` + + + +--- + +## 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._ + +### `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. + +### `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. + +### `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. + +### `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. + +### `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/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib) 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`). + +### `errorOnDeprecated` [boolean] + +Default: `false` + +Make calling deprecated APIs throw helpful error messages. Useful for easing the upgrade process. + +### `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. This function gets Jest's `globalConfig` object as a parameter. + +### `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. This function gets Jest's `globalConfig` object as a parameter. + +### `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"]` + +### `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). + +### `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` or `jest-preset.js` module at its top level. + +Presets may also be relative filesystem paths. + +```json +{ + "preset": "./node_modules/foo-bar/jest-preset.js" +} +``` + +### `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._ + +### `reporters` [array] + +Default: `undefined` + +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` + +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] + +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 +``` + +If you need to restrict your test-runner to only run in serial rather then being executed in parallel your class should have the property `isSerial` to be set as `true`. + +### `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. + +By adding a `@jest-environment` docblock at the top of the file, you can specify another environment to be used for all tests in that file: + +```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. + +_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] + +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] + +(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 +``` + +_Note: `testRegex` will try to detect test files using the **absolute file path** therefore having a folder with name that match it will run all the files as tests_ + +### `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, + "openHandles": Array, + "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: `[]` + +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-23.2/ExpectAPI.md b/website/versioned_docs/version-23.2/ExpectAPI.md new file mode 100644 index 000000000000..937026f7c2d8 --- /dev/null +++ b/website/versioned_docs/version-23.2/ExpectAPI.md @@ -0,0 +1,1137 @@ +--- +id: version-23.2-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); + expect({apples: 6, bananas: 3}).toEqual({ + apples: expect.toBeDivisibleBy(2), + bananas: expect.not.toBeDivisibleBy(2), + }); +}); +``` + +`expect.extends` also supports async matchers. Async matchers return a Promise so you will need to await the returned value. Let's use an example matcher to illustrate the usage of them. We are going to implement a very similar matcher than `toBeDivisibleBy`, only difference is that the divisible number is going to be pulled from an external source. + +```js +expect.extend({ + async toBeDivisibleByExternalValue(received) { + const externalValue = await getExternalValueFromRemoteSource(); + const pass = received % externalValue == 0; + if (pass) { + return { + message: () => + `expected ${received} not to be divisible by ${externalValue}`, + pass: true, + }; + } else { + return { + message: () => + `expected ${received} to be divisible by ${externalValue}`, + pass: false, + }; + } + }, +}); + +test('is divisible by external value', async () => { + await expect(100).toBeDivisibleByExternalValue(); + await expect(101).not.toBeDivisibleByExternalValue(); +}); +``` + +Matchers should return an object (or a Promise of 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 the 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(string | regexp)` + +`expect.not.stringMatching(string | regexp)` matches the 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 the received string that contains the exact expected string. + +### `expect.stringMatching(string | regexp)` + +`expect.stringMatching(string | regexp)` matches the 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` + +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` + +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)` + +Also under the alias: `.toBeCalledTimes(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'); +}); +``` + +### `.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)` + +Also under the alias: `.nthCalledWith(nthCall, arg1, arg2, ...)` + +If you have a mock function, you can use `.toHaveBeenNthCalledWith` to test what arguments it was nth called with. For example, let's say you have a `drinkEach(drink, Array)` function that applies `f` to a bunch of flavors, and you want to ensure that when you call it, the first flavor it operates on is `'lemon'` and the second one is `'octopus'`. You can write: + +```js +test('drinkEach drinks each drink', () => { + const drink = jest.fn(); + drinkEach(drink, ['lemon', 'octopus']); + expect(drink).toHaveBeenNthCalledWith(1, 'lemon'); + expect(drink).toHaveBeenNthCalledWith(2, 'octopus'); +}); +``` + +Note: the nth argument must be positive integer starting from 1. + +### `.toHaveReturned()` + +Also under the alias: `.toReturn()` + +If you have a mock function, you can use `.toHaveReturned` to test that the mock function successfully returned (i.e., did not throw an error) at least one time. For example, let's say you have a mock `drink` that returns `true`. You can write: + +```js +test('drinks returns', () => { + const drink = jest.fn(() => true); + + drink(); + + expect(drink).toHaveReturned(); +}); +``` + +### `.toHaveReturnedTimes(number)` + +Also under the alias: `.toReturnTimes(number)` + +Use `.toHaveReturnedTimes` to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times. Any calls to the mock function that throw an error are not counted toward the number of times the function returned. + +For example, let's say you have a mock `drink` that returns `true`. You can write: + +```js +test('drink returns twice', () => { + const drink = jest.fn(() => true); + + drink(); + drink(); + + expect(drink).toHaveReturnedTimes(2); +}); +``` + +### `.toHaveReturnedWith(value)` + +Also under the alias: `.toReturnWith(value)` + +Use `.toHaveReturnedWith` to ensure that a mock function returned a specific value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns La Croix', () => { + const beverage = {name: 'La Croix'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage); + + expect(drink).toHaveReturnedWith('La Croix'); +}); +``` + +### `.toHaveLastReturnedWith(value)` + +Also under the alias: `.lastReturnedWith(value)` + +Use `.toHaveLastReturnedWith` to test the specific value that a mock function last returned. If the last call to the mock function threw an error, then this matcher will fail no matter what value you provided as the expected return value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns La Croix (Orange) last', () => { + const beverage1 = {name: 'La Croix (Lemon)'}; + const beverage2 = {name: 'La Croix (Orange)'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage1); + drink(beverage2); + + expect(drink).toHaveLastReturnedWith('La Croix (Orange)'); +}); +``` + +### `.toHaveNthReturnedWith(nthCall, value)` + +Also under the alias: `.nthReturnedWith(nthCall, value)` + +Use `.toHaveNthReturnedWith` to test the specific value that a mock function returned for the nth call. If the nth call to the mock function threw an error, then this matcher will fail no matter what value you provided as the expected return value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns expected nth calls', () => { + const beverage1 = {name: 'La Croix (Lemon)'}; + const beverage2 = {name: 'La Croix (Orange)'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage1); + drink(beverage2); + + expect(drink).toHaveNthReturnedWith(1, 'La Croix (Lemon)'); + expect(drink).toHaveNthReturnedWith(2, 'La Croix (Orange)'); +}); +``` + +Note: the nth argument must be positive integer starting from 1. + +### `.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(propertyMatchers, snapshotName)` + +This ensures that a value matches the most recent snapshot. Check out [the Snapshot Testing guide](SnapshotTesting.md) for more information. + +The optional propertyMatchers argument allows you to specify asymmetric matchers which are verified instead of the exact values. + +The last argument allows you option to specify a 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._ + +### `.toStrictEqual(value)` + +Use `.toStrictEqual` to test that objects have the same types as well as structure. + +Differences from `.toEqual`: + +- Keys with `undefined` properties are checked. e.g. `{a: undefined, b: 2}` does not match `{b: 2}` when using `.toStrictEqual`. +- Object types are checked to be equal. e.g. A class instance with fields `a` and `b` will not equal a literal object with fields `a` and `b`. + +```js +class LaCroix { + constructor(flavor) { + this.flavor = flavor; + } +} + +describe('the La Croix cans on my desk', () => { + test('are not semantically the same', () => { + expect(new LaCroix('lemon')).toEqual({flavor: 'lemon'}); + expect(new LaCroix('lemon')).not.toStrictEqual({flavor: 'lemon'}); + }); +}); +``` + +### `.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 that should be contained in the error message, a class for the error, or a regex that should match the error message. 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 that the error message says "yuck" somewhere: these are equivalent + expect(drinkOctopus).toThrowError(/yuck/); + expect(drinkOctopus).toThrowError('yuck'); + + // Test the exact error message + expect(drinkOctopus).toThrowError(/^yuck, octopus flavor$/); + + // 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-23.2/GettingStarted.md b/website/versioned_docs/version-23.2/GettingStarted.md new file mode 100644 index 000000000000..7148f5c6d41c --- /dev/null +++ b/website/versioned_docs/version-23.2/GettingStarted.md @@ -0,0 +1,139 @@ +--- +id: version-23.2-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 a 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 + +### Generate a basic configuration file + +Based on your project, Jest will ask you a few questions and will create a basic configuration file with a short description for each option: + +```bash +jest --init +``` + +### 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-23.2/GlobalAPI.md b/website/versioned_docs/version-23.2/GlobalAPI.md new file mode 100644 index 000000000000..8cd941755365 --- /dev/null +++ b/website/versioned_docs/version-23.2/GlobalAPI.md @@ -0,0 +1,652 @@ +--- +id: version-23.2-api +title: Globals +original_id: api +--- + +In your test files, Jest puts each of these methods and objects into the global environment. You don't have to require or import anything to use them. + +## Methods + + + +--- + +## Reference + +### `afterAll(fn, timeout)` + +Runs a function after all the tests in this file have completed. If the function returns a promise or is a generator, Jest waits for that promise to resolve before continuing. + +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ + +This is often useful if you want to clean up some global setup state that is shared across tests. + +For example: + +```js +const globalDatabase = makeGlobalDatabase(); + +function cleanUpDatabase(db) { + db.cleanUp(); +} + +afterAll(() => { + cleanUpDatabase(globalDatabase); +}); + +test('can find things', () => { + return globalDatabase.find('thing', {}, results => { + expect(results.length).toBeGreaterThan(0); + }); +}); + +test('can insert a thing', () => { + return globalDatabase.insert('thing', makeThing(), response => { + expect(response.success).toBeTruthy(); + }); +}); +``` + +Here the `afterAll` ensures that `cleanUpDatabase` is called after all tests run. + +If `afterAll` is inside a `describe` block, it runs at the end of the describe block. + +If you want to run some cleanup after every test instead of after all tests, use `afterEach` instead. + +### `afterEach(fn, timeout)` + +Runs a function after each one of the tests in this file completes. If the function returns a promise or is a generator, Jest waits for that promise to resolve before continuing. + +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ + +This is often useful if you want to clean up some temporary state that is created by each test. + +For example: + +```js +const globalDatabase = makeGlobalDatabase(); + +function cleanUpDatabase(db) { + db.cleanUp(); +} + +afterEach(() => { + cleanUpDatabase(globalDatabase); +}); + +test('can find things', () => { + return globalDatabase.find('thing', {}, results => { + expect(results.length).toBeGreaterThan(0); + }); +}); + +test('can insert a thing', () => { + return globalDatabase.insert('thing', makeThing(), response => { + expect(response.success).toBeTruthy(); + }); +}); +``` + +Here the `afterEach` ensures that `cleanUpDatabase` is called after each test runs. + +If `afterEach` is inside a `describe` block, it only runs after the tests that are inside this describe block. + +If you want to run some cleanup just once, after all of the tests run, use `afterAll` instead. + +### `beforeAll(fn, timeout)` + +Runs a function before any of the tests in this file run. If the function returns a promise or is a generator, Jest waits for that promise to resolve before running tests. + +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ + +This is often useful if you want to set up some global state that will be used by many tests. + +For example: + +```js +const globalDatabase = makeGlobalDatabase(); + +beforeAll(() => { + // Clears the database and adds some testing data. + // Jest will wait for this promise to resolve before running tests. + return globalDatabase.clear().then(() => { + return globalDatabase.insert({testData: 'foo'}); + }); +}); + +// Since we only set up the database once in this example, it's important +// that our tests don't modify it. +test('can find things', () => { + return globalDatabase.find('thing', {}, results => { + expect(results.length).toBeGreaterThan(0); + }); +}); +``` + +Here the `beforeAll` ensures that the database is set up before tests run. If setup was synchronous, you could just do this without `beforeAll`. The key is that Jest will wait for a promise to resolve, so you can have asynchronous setup as well. + +If `beforeAll` is inside a `describe` block, it runs at the beginning of the describe block. + +If you want to run something before every test instead of before any test runs, use `beforeEach` instead. + +### `beforeEach(fn, timeout)` + +Runs a function before each of the tests in this file runs. If the function returns a promise or is a generator, Jest waits for that promise to resolve before running the test. + +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ + +This is often useful if you want to reset some global state that will be used by many tests. + +For example: + +```js +const globalDatabase = makeGlobalDatabase(); + +beforeEach(() => { + // Clears the database and adds some testing data. + // Jest will wait for this promise to resolve before running tests. + return globalDatabase.clear().then(() => { + return globalDatabase.insert({testData: 'foo'}); + }); +}); + +test('can find things', () => { + return globalDatabase.find('thing', {}, results => { + expect(results.length).toBeGreaterThan(0); + }); +}); + +test('can insert a thing', () => { + return globalDatabase.insert('thing', makeThing(), response => { + expect(response.success).toBeTruthy(); + }); +}); +``` + +Here the `beforeEach` ensures that the database is reset for each test. + +If `beforeEach` is inside a `describe` block, it runs for each test in the describe block. + +If you only need to run some setup code once, before any tests run, use `beforeAll` instead. + +### `describe(name, fn)` + +`describe(name, fn)` creates a block that groups together several related tests in one "test suite". For example, if you have a `myBeverage` object that is supposed to be delicious but not sour, you could test it with: + +```js +const myBeverage = { + delicious: true, + sour: false, +}; + +describe('my beverage', () => { + test('is delicious', () => { + expect(myBeverage.delicious).toBeTruthy(); + }); + + test('is not sour', () => { + expect(myBeverage.sour).toBeFalsy(); + }); +}); +``` + +This isn't required - you can just write the `test` blocks directly at the top level. But this can be handy if you prefer your tests to be organized into groups. + +You can also nest `describe` blocks if you have a hierarchy of tests: + +```js +const binaryStringToNumber = binString => { + if (!/^[01]+$/.test(binString)) { + throw new CustomError('Not a binary number.'); + } + + return parseInt(binString, 2); +}; + +describe('binaryStringToNumber', () => { + describe('given an invalid binary string', () => { + test('composed of non-numbers throws CustomError', () => { + expect(() => binaryStringToNumber('abc')).toThrowError(CustomError); + }); + + test('with extra whitespace throws CustomError', () => { + expect(() => binaryStringToNumber(' 100')).toThrowError(CustomError); + }); + }); + + describe('given a valid binary string', () => { + test('returns the correct number', () => { + expect(binaryStringToNumber('100')).toBe(4); + }); + }); +}); +``` + +### `describe.each(table)(name, fn)` + +Use `describe.each` if you keep duplicating the same test suites with different data. `describe.each` allows you to write the test suite once and pass data in. + +`describe.each` is available with two APIs: + +#### 1. `describe.each(table)(name, fn)` + +- `table`: `Array` of Arrays with the arguments that are passed into the `fn` for each row. + - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` +- `name`: `String` the title of the test suite. + - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args): + - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format). + - `%s`- String. + - `%d`- Number. + - `%i` - Integer. + - `%f` - Floating point value. + - `%j` - JSON. + - `%o` - Object. + - `%%` - single percent sign ('%'). This does not consume an argument. +- `fn`: `Function` the suite of tests to be ran, this is the function that will receive the parameters in each row as function arguments. + +Example: + +```js +describe.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + '.add(%i, %i)', + (a, b, expected) => { + test(`returns ${expected}`, () => { + expect(a + b).toBe(expected); + }); + + test(`returned value not be greater than ${expected}`, () => { + expect(a + b).not.toBeGreaterThan(expected); + }); + + test(`returned value not be less than ${expected}`, () => { + expect(a + b).not.toBeLessThan(expected); + }); + }, +); +``` + +#### 2. `` describe.each`table`(name, fn) `` + +- `table`: `Tagged Template Literal` + - First row of variable name column headings separated with `|` + - One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax. +- `name`: `String` the title of the test suite, use `$variable` to inject test data into the suite title from the tagged template expressions. + - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` +- `fn`: `Function` the suite of tests to be ran, this is the function that will receive the test data object. + +Example: + +```js +describe.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`('$a + $b', ({a, b, expected}) => { + test(`returns ${expected}`, () => { + expect(a + b).toBe(expected); + }); + + test(`returned value not be greater than ${expected}`, () => { + expect(a + b).not.toBeGreaterThan(expected); + }); + + test(`returned value not be less than ${expected}`, () => { + expect(a + b).not.toBeLessThan(expected); + }); +}); +``` + +### `describe.only(name, fn)` + +Also under the alias: `fdescribe(name, fn)` + +You can use `describe.only` if you want to run only one describe block: + +```js +describe.only('my beverage', () => { + test('is delicious', () => { + expect(myBeverage.delicious).toBeTruthy(); + }); + + test('is not sour', () => { + expect(myBeverage.sour).toBeFalsy(); + }); +}); + +describe('my other beverage', () => { + // ... will be skipped +}); +``` + +### `describe.only.each(table)(name, fn)` + +Also under the aliases: `fdescribe.each(table)(name, fn)` and `` fdescribe.each`table`(name, fn) `` + +Use `describe.only.each` if you want to only run specific tests suites of data driven tests. + +`describe.only.each` is available with two APIs: + +#### `describe.only.each(table)(name, fn)` + +```js +describe.only.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + '.add(%i, %i)', + (a, b, expected) => { + test(`returns ${expected}`, () => { + expect(a + b).toBe(expected); + }); + }, +); + +test('will not be ran', () => { + expect(1 / 0).toBe(Infinity); +}); +``` + +#### `` describe.only.each`table`(name, fn) `` + +```js +describe.only.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`('returns $expected when $a is added $b', ({a, b, expected}) => { + test('passes', () => { + expect(a + b).toBe(expected); + }); +}); + +test('will not be ran', () => { + expect(1 / 0).toBe(Infinity); +}); +``` + +### `describe.skip(name, fn)` + +Also under the alias: `xdescribe(name, fn)` + +You can use `describe.skip` if you do not want to run a particular describe block: + +```js +describe('my beverage', () => { + test('is delicious', () => { + expect(myBeverage.delicious).toBeTruthy(); + }); + + test('is not sour', () => { + expect(myBeverage.sour).toBeFalsy(); + }); +}); + +describe.skip('my other beverage', () => { + // ... will be skipped +}); +``` + +Using `describe.skip` is often just an easier alternative to temporarily commenting out a chunk of tests. + +### `describe.skip.each(table)(name, fn)` + +Also under the aliases: `xdescribe.each(table)(name, fn)` and `` xdescribe.each`table`(name, fn) `` + +Use `describe.skip.each` if you want to stop running a suite of data driven tests. + +`describe.skip.each` is available with two APIs: + +#### `describe.skip.each(table)(name, fn)` + +```js +describe.skip.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + '.add(%i, %i)', + (a, b, expected) => { + test(`returns ${expected}`, () => { + expect(a + b).toBe(expected); // will not be ran + }); + }, +); + +test('will be ran', () => { + expect(1 / 0).toBe(Infinity); +}); +``` + +#### `` describe.skip.each`table`(name, fn) `` + +```js +describe.skip.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`('returns $expected when $a is added $b', ({a, b, expected}) => { + test('will not be ran', () => { + expect(a + b).toBe(expected); // will not be ran + }); +}); + +test('will be ran', () => { + expect(1 / 0).toBe(Infinity); +}); +``` + +### `require.requireActual(moduleName)` + +Returns the actual module instead of a mock, bypassing all checks on whether the module should receive a mock implementation or not. + +### `require.requireMock(moduleName)` + +Returns a mock module instead of the actual module, bypassing all checks on whether the module should be required normally or not. + +### `test(name, fn, timeout)` + +Also under the alias: `it(name, fn, timeout)` + +All you need in a test file is the `test` method which runs a test. For example, let's say there's a function `inchesOfRain()` that should be zero. Your whole test could be: + +```js +test('did not rain', () => { + expect(inchesOfRain()).toBe(0); +}); +``` + +The first argument is the test name; the second argument is a function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ + +> Note: If a **promise is returned** from `test`, Jest will wait for the promise to resolve before letting the test complete. Jest will also wait if you **provide an argument to the test function**, usually called `done`. This could be handy when you want to test callbacks. See how to test async code [here](TestingAsyncCode.md#callbacks). + +For example, let's say `fetchBeverageList()` returns a promise that is supposed to resolve to a list that has `lemon` in it. You can test this with: + +```js +test('has lemon in it', () => { + return fetchBeverageList().then(list => { + expect(list).toContain('lemon'); + }); +}); +``` + +Even though the call to `test` will return right away, the test doesn't complete until the promise resolves as well. + +### `test.each(table)(name, fn)` + +Also under the alias: `it.each(table)(name, fn)` and `` it.each`table`(name, fn) `` + +Use `test.each` if you keep duplicating the same test with different data. `test.each` allows you to write the test once and pass data in. + +`test.each` is available with two APIs: + +#### 1. `test.each(table)(name, fn)` + +- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. + - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` +- `name`: `String` the title of the test block. + - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args): + - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format). + - `%s`- String. + - `%d`- Number. + - `%i` - Integer. + - `%f` - Floating point value. + - `%j` - JSON. + - `%o` - Object. + - `%%` - single percent sign ('%'). This does not consume an argument. +- `fn`: `Function` the test to be ran, this is the function that will receive the parameters in each row as function arguments. + +Example: + +```js +test.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + '.add(%i, %i)', + (a, b, expected) => { + expect(a + b).toBe(expected); + }, +); +``` + +#### 2. `` test.each`table`(name, fn) `` + +- `table`: `Tagged Template Literal` + - First row of variable name column headings separated with `|` + - One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax. +- `name`: `String` the title of the test, use `$variable` to inject test data into the test title from the tagged template expressions. + - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` +- `fn`: `Function` the test to be ran, this is the function that will receive the test data object. + +Example: + +```js +test.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`('returns $expected when $a is added $b', ({a, b, expected}) => { + expect(a + b).toBe(expected); +}); +``` + +### `test.only(name, fn, timeout)` + +Also under the aliases: `it.only(name, fn, timeout)` or `fit(name, fn, timeout)` + +When you are debugging a large test file, you will often only want to run a subset of tests. You can use `.only` to specify which tests are the only ones you want to run in that test file. + +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ + +For example, let's say you had these tests: + +```js +test.only('it is raining', () => { + expect(inchesOfRain()).toBeGreaterThan(0); +}); + +test('it is not snowing', () => { + expect(inchesOfSnow()).toBe(0); +}); +``` + +Only the "it is raining" test will run in that test file, since it is run with `test.only`. + +Usually you wouldn't check code using `test.only` into source control - you would use it just for debugging, and remove it once you have fixed the broken tests. + +### `test.only.each(table)(name, fn)` + +Also under the aliases: `it.only.each(table)(name, fn)`, `fit.each(table)(name, fn)`, `` it.only.each`table`(name, fn) `` and `` fit.each`table`(name, fn) `` + +Use `test.only.each` if you want to only run specific tests with different test data. + +`test.only.each` is available with two APIs: + +#### `test.only.each(table)(name, fn)` + +```js +test.only.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + '.add(%i, %i)', + (a, b, expected) => { + expect(a + b).toBe(expected); + }, +); + +test('will not be ran', () => { + expect(1 / 0).toBe(Infinity); +}); +``` + +#### `` test.only.each`table`(name, fn) `` + +```js +test.only.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`('returns $expected when $a is added $b', ({a, b, expected}) => { + expect(a + b).toBe(expected); +}); + +test('will not be ran', () => { + expect(1 / 0).toBe(Infinity); +}); +``` + +### `test.skip(name, fn)` + +Also under the aliases: `it.skip(name, fn)` or `xit(name, fn)` or `xtest(name, fn)` + +When you are maintaining a large codebase, you may sometimes find a test that is temporarily broken for some reason. If you want to skip running this test, but you don't want to just delete this code, you can use `test.skip` to specify some tests to skip. + +For example, let's say you had these tests: + +```js +test('it is raining', () => { + expect(inchesOfRain()).toBeGreaterThan(0); +}); + +test.skip('it is not snowing', () => { + expect(inchesOfSnow()).toBe(0); +}); +``` + +Only the "it is raining" test will run, since the other test is run with `test.skip`. + +You could simply comment the test out, but it's often a bit nicer to use `test.skip` because it will maintain indentation and syntax highlighting. + +### `test.skip.each(table)(name, fn)` + +Also under the aliases: `it.skip.each(table)(name, fn)`, `xit.each(table)(name, fn)`, `xtest.each(table)(name, fn)`, `` it.skip.each`table`(name, fn) ``, `` xit.each`table`(name, fn) `` and `` xtest.each`table`(name, fn) `` + +Use `test.skip.each` if you want to stop running a collection of data driven tests. + +`test.skip.each` is available with two APIs: + +#### `test.skip.each(table)(name, fn)` + +```js +test.skip.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + '.add(%i, %i)', + (a, b, expected) => { + expect(a + b).toBe(expected); // will not be ran + }, +); + +test('will be ran', () => { + expect(1 / 0).toBe(Infinity); +}); +``` + +#### `` test.skip.each`table`(name, fn) `` + +```js +test.skip.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`('returns $expected when $a is added $b', ({a, b, expected}) => { + expect(a + b).toBe(expected); // will not be ran +}); + +test('will be ran', () => { + expect(1 / 0).toBe(Infinity); +}); +``` diff --git a/website/versioned_docs/version-23.2/JestObjectAPI.md b/website/versioned_docs/version-23.2/JestObjectAPI.md new file mode 100644 index 000000000000..3ec19dc06965 --- /dev/null +++ b/website/versioned_docs/version-23.2/JestObjectAPI.md @@ -0,0 +1,476 @@ +--- +id: version-23.2-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()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.resetAllMocks()` + +Resets the state of all mocks. Equivalent to calling [`.mockReset()`](MockFunctionAPI.md#mockfnmockreset) on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.restoreAllMocks()` + +Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) 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)` + +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.mockRestore(); +}); +``` + +### `jest.spyOn(object, methodName, accessType?)` + +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 = audio; +``` + +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.mockRestore(); +}); + +const audio = require('./audio'); + +test('plays audio', () => { + const spy = jest.spyOn(audio, 'volume', 'set'); // we pass 'set' + audio.volume = 100; + + expect(spy).toHaveBeenCalled(); + expect(audio.volume).toBe(100); + + spy.mockRestore(); +}); +``` diff --git a/website/versioned_docs/version-23.2/MockFunctions.md b/website/versioned_docs/version-23.2/MockFunctions.md new file mode 100644 index 000000000000..aef9e6b66eea --- /dev/null +++ b/website/versioned_docs/version-23.2/MockFunctions.md @@ -0,0 +1,287 @@ +--- +id: version-23.2-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); + +// The return value of the first call to the function was 42 +expect(mockCallback.mock.results[0].value).toBe(42); +``` + +## `.mock` property + +All mock functions have this special `.mock` property, which is where data about how the function has been called and what the function returned 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, instantiated, or what they returned: + +```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'); + +// The return value of the first call to the function was 'return value' +expect(someMockFunction.mock.results[0].value).toBe('return value'); + +// 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 `mockResolvedValue` 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 following depending on your use case: + // axios.get.mockImplementation(() => 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 + +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-23.2/MongoDB.md b/website/versioned_docs/version-23.2/MongoDB.md new file mode 100644 index 000000000000..71d9ede3401f --- /dev/null +++ b/website/versioned_docs/version-23.2/MongoDB.md @@ -0,0 +1,141 @@ +--- +id: version-23.2-mongodb +title: Using with MongoDB +original_id: mongodb +--- + +With the [Global Setup/Teardown](Configuration.md#globalsetup-string) and [Async Test Environment](Configuration.md#testenvironment-string) APIs, Jest can work smoothly with [MongoDB](https://www.mongodb.com/). + +## A jest-mongodb example + +The basic idea is to: + +1. Spin up in-memory mongodb server +2. Export a global variable with mongo URI +3. Write tests for queries / aggregations using a real database ✨ +4. Shut down mongodb server using Global Teardown + +Here's an example of the GlobalSetup script + +```js +// setup.js +const path = require('path'); + +const fs = require('fs'); + +const MongodbMemoryServer = require('mongodb-memory-server'); + +const globalConfigPath = path.join(__dirname, 'globalConfig.json'); + +const mongoServer = new MongodbMemoryServer.MongoMemoryServer(); + +module.exports = async function() { + const mongoConfig = { + mongoDBName: 'jest', + mongoUri: await mongoServer.getConnectionString(), + }; + + // Write global config to disk because all tests run in different contexts. + fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig)); + + // Set reference to mongod in order to close the server during teardown. + global.__MONGOD__ = mongoServer; +}; +``` + +Then we need a custom Test Environment for Mongo + +```js +// mongo-environment.js +const NodeEnvironment = require('jest-environment-node'); + +const path = require('path'); + +const fs = require('fs'); + +const globalConfigPath = path.join(__dirname, 'globalConfig.json'); + +class MongoEnvironment extends NodeEnvironment { + constructor(config) { + super(config); + } + + async setup() { + console.log('Setup MongoDB Test Environment'); + + const globalConfig = JSON.parse(fs.readFileSync(globalConfigPath, 'utf-8')); + + this.global.__MONGO_URI__ = globalConfig.mongoUri; + this.global.__MONGO_DB_NAME__ = globalConfig.mongoDBName; + + await super.setup(); + } + + async teardown() { + console.log('Teardown MongoDB Test Environment'); + + await super.teardown(); + } + + runScript(script) { + return super.runScript(script); + } +} +``` + +Finally we can shut down mongodb server + +```js +// teardown.js +module.exports = async function() { + await global.__MONGOD__.stop(); +}; +``` + +With all the things set up, we can now write our tests like this: + +```js +// test.js +const {MongoClient} = require('mongodb'); + +let connection; +let db; + +beforeAll(async () => { + connection = await MongoClient.connect(global.__MONGO_URI__); + db = await connection.db(global.__MONGO_DB_NAME__); +}); + +afterAll(async () => { + await connection.close(); + await db.close(); +}); + +it('should aggregate docs from collection', async () => { + const files = db.collection('files'); + + await files.insertMany([ + {type: 'Document'}, + {type: 'Video'}, + {type: 'Image'}, + {type: 'Document'}, + {type: 'Image'}, + {type: 'Document'}, + ]); + + const topFiles = await files + .aggregate([ + {$group: {_id: '$type', count: {$sum: 1}}}, + {$sort: {count: -1}}, + ]) + .toArray(); + + expect(topFiles).toEqual([ + {_id: 'Document', count: 3}, + {_id: 'Image', count: 2}, + {_id: 'Video', count: 1}, + ]); +}); +``` + +Here's the code of [full working example](https://github.com/vladgolubev/jest-mongodb). diff --git a/website/versioned_docs/version-23.2/Puppeteer.md b/website/versioned_docs/version-23.2/Puppeteer.md new file mode 100644 index 000000000000..c7b76936e353 --- /dev/null +++ b/website/versioned_docs/version-23.2/Puppeteer.md @@ -0,0 +1,121 @@ +--- +id: version-23.2-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](https://github.com/smooth-code/jest-puppeteer) provides all required configuration to run your tests using Puppeteer. + +1. First install `jest-puppeteer` + +``` +yarn add --dev jest-puppeteer +``` + +2. Specify preset in your Jest configuration: + +```json +{ + "preset": "jest-puppeteer" +} +``` + +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 + // this global is only available in the teardown but not in TestEnvironments + global.__BROWSER_GLOBAL__ = browser; + + // use the file system to expose 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_GLOBAL__.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-23.2/WatchPlugins.md b/website/versioned_docs/version-23.2/WatchPlugins.md new file mode 100644 index 000000000000..a73f69edc4e6 --- /dev/null +++ b/website/versioned_docs/version-23.2/WatchPlugins.md @@ -0,0 +1,150 @@ +--- +id: version-23.2-watch-plugins +title: Watch Plugins +original_id: watch-plugins +--- + +The Jest watch plugin system provides a way to hook into specific parts of Jest and to define watch mode menu prompts that execute code on key press. Combined, these features allow you to develop interactive experiences custom for your workflow. + +## Watch Plugin Interface + +```javascript +class MyWatchPlugin { + // Add hooks to Jest lifecycle events + apply(jestHooks) {} + + // Get the prompt information for interactive plugins + getUsageInfo(globalConfig) {} + + // Executed when the key from `getUsageInfo` is input + run(globalConfig, updateConfigAndRun) {} +} +``` + +## Hooking into Jest + +To connect your watch plugin to Jest, add its path under `watchPlugins` in your Jest configuration: + +```javascript +// jest.config.js +module.exports = { + // ... + watchPlugins: ['path/to/yourWatchPlugin'], +}; +``` + +Custom watch plugins can add hooks to Jest events. These hooks can be added either with or without having an interactive key in the watch mode menu. + +### `apply(jestHooks)` + +Jest hooks can be attached by implementing the `apply` method. This method receives a `jestHooks` argument that allows the plugin to hook into specific parts of the lifecycle of a test run. + +```javascript +class MyWatchPlugin { + apply(jestHooks) {} +} +``` + +Below are the hooks available in Jest. + +#### `jestHooks.shouldRunTestSuite(testPath)` + +Returns a boolean (or `Promise`) for handling asynchronous operations) to specify if a test should be run or not. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.shouldRunTestSuite(testPath => { + return testPath.includes('my-keyword'); + }); + + // or a promise + jestHooks.shouldRunTestSuite(testPath => { + return Promise.resolve(testPath.includes('my-keyword')); + }); + } +} +``` + +#### `jestHooks.onTestRunComplete(results)` + +Gets called at the end of every test run. It has the test results as an argument. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.onTestRunComplete(results => { + this._hasSnapshotFailure = results.snapshot.failure; + }); + } +} +``` + +#### `jestHooks.onFileChange({projects})` + +Gets called whenever there is a change in the file system + +- `projects: Array`: Includes all the test paths that Jest is watching. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.onFileChange(({projects}) => { + this._projects = projects; + }); + } +} +``` + +## Watch Menu Integration + +Custom watch plugins can also add or override functionality to the watch menu by specifying a key/prompt pair in `getUsageInfo` method and a `run` method for the execution of the key. + +### `getUsageInfo(globalConfig)` + +To add a key to the watch menu, implement the `getUsageInfo` method, returning a key and the prompt: + +```javascript +class MyWatchPlugin { + getUsageInfo(globalConfig) { + return { + key: 's', + prompt: 'do something', + }; + } +} +``` + +This will add a line in the watch mode menu _(`› Press s to do something.`)_ + +```text +Watch Usage + › Press p to filter by a filename regex pattern. + › Press t to filter by a test name regex pattern. + › Press q to quit watch mode. + › Press s to do something. // <-- This is our plugin + › Press Enter to trigger a test run. +``` + +**Note**: If the key for your plugin already exists as a default key, your plugin will override that key. + +### `run(globalConfig, updateConfigAndRun)` + +To handle key press events from the key returned by `getUsageInfo`, you can implement the `run` method. This method returns a `Promise` that can be resolved when the plugin wants to return control to Jest. The `boolean` specifies if Jest should rerun the tests after it gets the control back. + +- `globalConfig`: A representation of Jest's current global configuration +- `updateConfigAndRun`: Allows you to trigger a test run while the interactive plugin is running. + +```javascript +class MyWatchPlugin { + run(globalConfig, updateConfigAndRun) { + // do something. + } +} +``` diff --git a/website/versioned_docs/version-23.3/CLI.md b/website/versioned_docs/version-23.3/CLI.md new file mode 100644 index 000000000000..3c67703f4bfc --- /dev/null +++ b/website/versioned_docs/version-23.3/CLI.md @@ -0,0 +1,296 @@ +--- +id: version-23.3-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` + +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` + +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=` + +A glob pattern 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. + +### `--detectOpenHandles` + +Attempt to collect and print open handles preventing Jest from exiting cleanly. Use this in cases where you need to use `--forceExit` in order for Jest to exit to potentially track down the reason. Implemented using [`async_hooks`](https://nodejs.org/api/async_hooks.html), so it only works in Node 8 and newer. + +### `--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`. + +### `--errorOnDeprecated` + +Make calling deprecated APIs throw helpful error messages. Useful for easing the upgrade process. + +### `--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. Can be used together with `--coverage` to include a test coverage for the source files, no duplicate `--collectCoverageFrom` arguments needed. + +### `--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. You can use `--detectOpenHandles` to help track it down._ + +### `--help` + +Show the help information, similar to this page. + +### `--init` + +Generate a basic configuration file. Based on your project, Jest will ask you a few questions that will help to generate a `jest.config.js` file with a short description for each option. + +### `--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. + +### `--reporters` + +Run tests with specified reporters. [Reporter options](configuration#reporters-array-modulename-modulename-options) are not available via CLI. Example with multiple reporters: + +`jest --reporters="default" --reporters="jest-junit"` + +### `--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 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`. + +_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ + +### `--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-23.3/Configuration.md b/website/versioned_docs/version-23.3/Configuration.md new file mode 100644 index 000000000000..38245c0864a5 --- /dev/null +++ b/website/versioned_docs/version-23.3/Configuration.md @@ -0,0 +1,910 @@ +--- +id: version-23.3-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. + +### Defaults + +You can retrieve Jest's default options to expand them if needed: + +```js +// jest.config.js +const {defaults} = require('jest-config'); +module.exports = { + // ... + moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'], + // ... +}; +``` + + + +--- + +## 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._ + +### `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. + +### `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. + +### `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. + +### `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. + +### `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/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib) 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`). + +### `errorOnDeprecated` [boolean] + +Default: `false` + +Make calling deprecated APIs throw helpful error messages. Useful for easing the upgrade process. + +### `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. This function gets Jest's `globalConfig` object as a parameter. + +### `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. This function gets Jest's `globalConfig` object as a parameter. + +### `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"]` + +### `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). + +### `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` or `jest-preset.js` module at its top level. + +Presets may also be relative filesystem paths. + +```json +{ + "preset": "./node_modules/foo-bar/jest-preset.js" +} +``` + +### `prettierPath` [string] + +Default: `'prettier'` + +Sets the path to the [`prettier`](https://prettier.io/) node module used to update inline snapshots. + +### `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._ + +### `reporters` [array] + +Default: `undefined` + +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` + +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] + +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 +``` + +If you need to restrict your test-runner to only run in serial rather then being executed in parallel your class should have the property `isSerial` to be set as `true`. + +### `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. + +By adding a `@jest-environment` docblock at the top of the file, you can specify another environment to be used for all tests in that file: + +```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. + +_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] + +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] + +(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 +``` + +_Note: `testRegex` will try to detect test files using the **absolute file path** therefore having a folder with name that match it will run all the files as tests_ + +### `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, + "openHandles": Array, + "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: `[]` + +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-23.3/ExpectAPI.md b/website/versioned_docs/version-23.3/ExpectAPI.md new file mode 100644 index 000000000000..1a466cd04d62 --- /dev/null +++ b/website/versioned_docs/version-23.3/ExpectAPI.md @@ -0,0 +1,1149 @@ +--- +id: version-23.3-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); + expect({apples: 6, bananas: 3}).toEqual({ + apples: expect.toBeDivisibleBy(2), + bananas: expect.not.toBeDivisibleBy(2), + }); +}); +``` + +`expect.extends` also supports async matchers. Async matchers return a Promise so you will need to await the returned value. Let's use an example matcher to illustrate the usage of them. We are going to implement a very similar matcher than `toBeDivisibleBy`, only difference is that the divisible number is going to be pulled from an external source. + +```js +expect.extend({ + async toBeDivisibleByExternalValue(received) { + const externalValue = await getExternalValueFromRemoteSource(); + const pass = received % externalValue == 0; + if (pass) { + return { + message: () => + `expected ${received} not to be divisible by ${externalValue}`, + pass: true, + }; + } else { + return { + message: () => + `expected ${received} to be divisible by ${externalValue}`, + pass: false, + }; + } + }, +}); + +test('is divisible by external value', async () => { + await expect(100).toBeDivisibleByExternalValue(); + await expect(101).not.toBeDivisibleByExternalValue(); +}); +``` + +Matchers should return an object (or a Promise of 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 the 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(string | regexp)` + +`expect.not.stringMatching(string | regexp)` matches the 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 the received string that contains the exact expected string. + +### `expect.stringMatching(string | regexp)` + +`expect.stringMatching(string | regexp)` matches the 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` + +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` + +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)` + +Also under the alias: `.toBeCalledTimes(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'); +}); +``` + +### `.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)` + +Also under the alias: `.nthCalledWith(nthCall, arg1, arg2, ...)` + +If you have a mock function, you can use `.toHaveBeenNthCalledWith` to test what arguments it was nth called with. For example, let's say you have a `drinkEach(drink, Array)` function that applies `f` to a bunch of flavors, and you want to ensure that when you call it, the first flavor it operates on is `'lemon'` and the second one is `'octopus'`. You can write: + +```js +test('drinkEach drinks each drink', () => { + const drink = jest.fn(); + drinkEach(drink, ['lemon', 'octopus']); + expect(drink).toHaveBeenNthCalledWith(1, 'lemon'); + expect(drink).toHaveBeenNthCalledWith(2, 'octopus'); +}); +``` + +Note: the nth argument must be positive integer starting from 1. + +### `.toHaveReturned()` + +Also under the alias: `.toReturn()` + +If you have a mock function, you can use `.toHaveReturned` to test that the mock function successfully returned (i.e., did not throw an error) at least one time. For example, let's say you have a mock `drink` that returns `true`. You can write: + +```js +test('drinks returns', () => { + const drink = jest.fn(() => true); + + drink(); + + expect(drink).toHaveReturned(); +}); +``` + +### `.toHaveReturnedTimes(number)` + +Also under the alias: `.toReturnTimes(number)` + +Use `.toHaveReturnedTimes` to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times. Any calls to the mock function that throw an error are not counted toward the number of times the function returned. + +For example, let's say you have a mock `drink` that returns `true`. You can write: + +```js +test('drink returns twice', () => { + const drink = jest.fn(() => true); + + drink(); + drink(); + + expect(drink).toHaveReturnedTimes(2); +}); +``` + +### `.toHaveReturnedWith(value)` + +Also under the alias: `.toReturnWith(value)` + +Use `.toHaveReturnedWith` to ensure that a mock function returned a specific value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns La Croix', () => { + const beverage = {name: 'La Croix'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage); + + expect(drink).toHaveReturnedWith('La Croix'); +}); +``` + +### `.toHaveLastReturnedWith(value)` + +Also under the alias: `.lastReturnedWith(value)` + +Use `.toHaveLastReturnedWith` to test the specific value that a mock function last returned. If the last call to the mock function threw an error, then this matcher will fail no matter what value you provided as the expected return value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns La Croix (Orange) last', () => { + const beverage1 = {name: 'La Croix (Lemon)'}; + const beverage2 = {name: 'La Croix (Orange)'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage1); + drink(beverage2); + + expect(drink).toHaveLastReturnedWith('La Croix (Orange)'); +}); +``` + +### `.toHaveNthReturnedWith(nthCall, value)` + +Also under the alias: `.nthReturnedWith(nthCall, value)` + +Use `.toHaveNthReturnedWith` to test the specific value that a mock function returned for the nth call. If the nth call to the mock function threw an error, then this matcher will fail no matter what value you provided as the expected return value. + +For example, let's say you have a mock `drink` that returns the name of the beverage that was consumed. You can write: + +```js +test('drink returns expected nth calls', () => { + const beverage1 = {name: 'La Croix (Lemon)'}; + const beverage2 = {name: 'La Croix (Orange)'}; + const drink = jest.fn(beverage => beverage.name); + + drink(beverage1); + drink(beverage2); + + expect(drink).toHaveNthReturnedWith(1, 'La Croix (Lemon)'); + expect(drink).toHaveNthReturnedWith(2, 'La Croix (Orange)'); +}); +``` + +Note: the nth argument must be positive integer starting from 1. + +### `.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(propertyMatchers, snapshotName)` + +This ensures that a value matches the most recent snapshot. Check out [the Snapshot Testing guide](SnapshotTesting.md) for more information. + +The optional `propertyMatchers` argument allows you to specify asymmetric matchers which are verified instead of the exact values. + +The last argument allows you option to specify a 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._ + +### `.toMatchInlineSnapshot(propertyMatchers, inlineSnapshot)` + +Ensures that a value matches the most recent snapshot. Unlike [`.toMatchSnapshot()`](#tomatchsnapshotpropertymatchers-snapshotname), the snapshots will be written to the current source file, inline. + +Check out the section on [Inline Snapshots](./SnapshotTesting.md#inline-snapshots) for more info. + +### `.toStrictEqual(value)` + +Use `.toStrictEqual` to test that objects have the same types as well as structure. + +Differences from `.toEqual`: + +- Keys with `undefined` properties are checked. e.g. `{a: undefined, b: 2}` does not match `{b: 2}` when using `.toStrictEqual`. +- Object types are checked to be equal. e.g. A class instance with fields `a` and `b` will not equal a literal object with fields `a` and `b`. + +```js +class LaCroix { + constructor(flavor) { + this.flavor = flavor; + } +} + +describe('the La Croix cans on my desk', () => { + test('are not semantically the same', () => { + expect(new LaCroix('lemon')).toEqual({flavor: 'lemon'}); + expect(new LaCroix('lemon')).not.toStrictEqual({flavor: 'lemon'}); + }); +}); +``` + +### `.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 that should be contained in the error message, a class for the error, or a regex that should match the error message. 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 that the error message says "yuck" somewhere: these are equivalent + expect(drinkOctopus).toThrowError(/yuck/); + expect(drinkOctopus).toThrowError('yuck'); + + // Test the exact error message + expect(drinkOctopus).toThrowError(/^yuck, octopus flavor$/); + + // 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. + +### `.toThrowErrorMatchingInlineSnapshot()` + +This matcher is much like [`.toThrowErrorMatchingSnapshot`](#tothrowerrormatchingsnapshot), except instead of writing the snapshot value to a `.snap` file, it will be written into the source code automatically. + +Check out the section on [Inline Snapshots](./SnapshotTesting.md#inline-snapshots) for more info. diff --git a/website/versioned_docs/version-23.3/JestObjectAPI.md b/website/versioned_docs/version-23.3/JestObjectAPI.md new file mode 100644 index 000000000000..178269186892 --- /dev/null +++ b/website/versioned_docs/version-23.3/JestObjectAPI.md @@ -0,0 +1,508 @@ +--- +id: version-23.3-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.retryTimes()`](#jestretrytimes) +- [`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()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.resetAllMocks()` + +Resets the state of all mocks. Equivalent to calling [`.mockReset()`](MockFunctionAPI.md#mockfnmockreset) on every mocked function. + +Returns the `jest` object for chaining. + +### `jest.restoreAllMocks()` + +Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) 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.retryTimes()` + +Runs failed tests n-times until they pass or until the max number of retries are exhausted. This only works with jest-circus! + +Example in a test: + +```js +jest.retryTimes(3); +test('will fail', () => { + expect(true).toBe(false); +}); +``` + +To run with jest circus: + +Install jest-circus + +``` +yarn add --dev jest-circus +``` + +Then set as the testRunner in your jest config: + +```js +module.exports = { + testRunner: 'jest-circus/runner', +}; +``` + +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)` + +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.mockRestore(); +}); +``` + +### `jest.spyOn(object, methodName, accessType?)` + +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 = audio; +``` + +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.mockRestore(); +}); + +const audio = require('./audio'); + +test('plays audio', () => { + const spy = jest.spyOn(audio, 'volume', 'set'); // we pass 'set' + audio.volume = 100; + + expect(spy).toHaveBeenCalled(); + expect(audio.volume).toBe(100); + + spy.mockRestore(); +}); +``` diff --git a/website/versioned_docs/version-23.3/SnapshotTesting.md b/website/versioned_docs/version-23.3/SnapshotTesting.md new file mode 100644 index 000000000000..aab198d0d11d --- /dev/null +++ b/website/versioned_docs/version-23.3/SnapshotTesting.md @@ -0,0 +1,293 @@ +--- +id: version-23.3-snapshot-testing +title: Snapshot Testing +original_id: snapshot-testing +--- + +Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly. + +A typical snapshot test case for a mobile app renders a UI component, takes a screenshot, then compares it to a reference image stored alongside the test. The test will fail if the two images do not match: either the change is unexpected, or the screenshot needs to be updated to the new version of the UI component. + +## Snapshot Testing with Jest + +A similar approach can be taken when it comes to testing your React components. Instead of rendering the graphical UI, which would require building the entire app, you can use a test renderer to quickly generate a serializable value for your React tree. Consider this [example test](https://github.com/facebook/jest/blob/master/examples/snapshot/__tests__/link.react.test.js) for a simple [Link component](https://github.com/facebook/jest/blob/master/examples/snapshot/Link.react.js): + +```javascript +import React from 'react'; +import Link from '../Link.react'; +import renderer from 'react-test-renderer'; + +it('renders correctly', () => { + const tree = renderer + .create(Facebook) + .toJSON(); + expect(tree).toMatchSnapshot(); +}); +``` + +The first time this test is run, Jest creates a [snapshot file](https://github.com/facebook/jest/blob/master/examples/snapshot/__tests__/__snapshots__/link.react.test.js.snap) that looks like this: + +```javascript +exports[`renders correctly 1`] = ` + + Facebook + +`; +``` + +The snapshot artifact should be committed alongside code changes, and reviewed as part of your code review process. Jest uses [pretty-format](https://github.com/facebook/jest/tree/master/packages/pretty-format) to make snapshots human-readable during code review. On subsequent test runs Jest will simply compare the rendered output with the previous snapshot. If they match, the test will pass. If they don't match, either the test runner found a bug in your code that should be fixed, or the implementation has changed and the snapshot needs to be updated. + +More information on how snapshot testing works and why we built it can be found on the [release blog post](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html). We recommend reading [this blog post](http://benmccormick.org/2016/09/19/testing-with-jest-snapshots-first-impressions/) to get a good sense of when you should use snapshot testing. We also recommend watching this [egghead video](https://egghead.io/lessons/javascript-use-jest-s-snapshot-testing-feature?pl=testing-javascript-with-jest-a36c4074) on Snapshot Testing with Jest. + +### Updating Snapshots + +It's straightforward to spot when a snapshot test fails after a bug has been introduced. When that happens, go ahead and fix the issue and make sure your snapshot tests are passing again. Now, let's talk about the case when a snapshot test is failing due to an intentional implementation change. + +One such situation can arise if we intentionally change the address the Link component in our example is pointing to. + +```javascript +// Updated test case with a Link to a different address +it('renders correctly', () => { + const tree = renderer + .create(Instagram) + .toJSON(); + expect(tree).toMatchSnapshot(); +}); +``` + +In that case, Jest will print this output: + +![](/img/content/failedSnapshotTest.png) + +Since we just updated our component to point to a different address, it's reasonable to expect changes in the snapshot for this component. Our snapshot test case is failing because the snapshot for our updated component no longer matches the snapshot artifact for this test case. + +To resolve this, we will need to update our snapshot artifacts. You can run Jest with a flag that will tell it to re-generate snapshots: + +```bash +jest --updateSnapshot +``` + +Go ahead and accept the changes by running the above command. You may also use the equivalent single-character `-u` flag to re-generate snapshots if you prefer. This will re-generate snapshot artifacts for all failing snapshot tests. If we had any additional failing snapshot tests due to an unintentional bug, we would need to fix the bug before re-generating snapshots to avoid recording snapshots of the buggy behavior. + +If you'd like to limit which snapshot test cases get re-generated, you can pass an additional `--testNamePattern` flag to re-record snapshots only for those tests that match the pattern. + +You can try out this functionality by cloning the [snapshot example](https://github.com/facebook/jest/tree/master/examples/snapshot), modifying the `Link` component, and running Jest. + +### Interactive Snapshot Mode + +Failed snapshots can also be updated interactively in watch mode: + +![](/img/content/interactiveSnapshot.png) + +Once you enter Interactive Snapshot Mode, Jest will step you through the failed snapshots one test at a time and give you the opportunity to review the failed output. + +From here you can choose to update that snapshot or skip to the next: + +![](/img/content/interactiveSnapshotUpdate.gif) + +Once you're finished, Jest will give you a summary before returning back to watch mode: + +![](/img/content/interactiveSnapshotDone.png) + +### Inline Snapshots + +Inline snapshots behave identically to external snapshots (`.snap` files), except the snapshot values are written automatically back into the source code. This means you can get the benefits of automatically generated snapshots without having to switch to an external file to make sure the correct value was written. + +> Inline snapshots are powered by [Prettier](https://prettier.io). To use inline snapshots you must have `prettier` installed in your project. Your Prettier configuration will be respected when writing to test files. +> +> If you have `prettier` installed in a location where Jest can't find it, you can tell Jest how to find it using the [`"prettierPath"`](./Configuration.md#prettierpath-string) configuration property. + +**Example:** + +First, you write a test, calling `.toMatchInlineSnapshot()` with no arguments: + +```javascript +it('renders correctly', () => { + const tree = renderer + .create(Prettier) + .toJSON(); + expect(tree).toMatchInlineSnapshot(); +}); +``` + +The next time you run Jest, `tree` will be evaluated, and a snapshot will be written as an argument to `toMatchInlineSnapshot`: + +```javascript +it('renders correctly', () => { + const tree = renderer + .create(Prettier) + .toJSON(); + expect(tree).toMatchInlineSnapshot(` + + Prettier + +`); +}); +``` + +That's all there is to it! You can even update the snapshots with `--updateSnapshot` or using the `u` key in `--watch` mode. + +### Property Matchers + +Often there are fields in the object you want to snapshot which are generated (like IDs and Dates). If you try to snapshot these objects, they will force the snapshot to fail on every run: + +```javascript +it('will fail every time', () => { + const user = { + createdAt: new Date(), + id: Math.floor(Math.random() * 20), + name: 'LeBron James', + }; + + expect(user).toMatchSnapshot(); +}); + +// Snapshot +exports[`will fail every time 1`] = ` +Object { + "createdAt": 2018-05-19T23:36:09.816Z, + "id": 3, + "name": "LeBron James", +} +`; +``` + +For these cases, Jest allows providing an asymmetric matcher for any property. These matchers are checked before the snapshot is written or tested, and then saved to the snapshot file instead of the received value: + +```javascript +it('will check the matchers and pass', () => { + const user = { + createdAt: new Date(), + id: Math.floor(Math.random() * 20), + name: 'LeBron James', + }; + + expect(user).toMatchSnapshot({ + createdAt: expect.any(Date), + id: expect.any(Number), + }); +}); + +// Snapshot +exports[`will check the matchers and pass 1`] = ` +Object { + "createdAt": Any, + "id": Any, + "name": "LeBron James", +} +`; +``` + +## Best Practices + +Snapshots are a fantastic tool for identifying unexpected interface changes within your application – whether that interface is an API response, UI, logs, or error messages. As with any testing strategy, there are some best-practices you should be aware of, and guidelines you should follow, in order to use them effectively. + +### 1. Treat snapshots as code + +Commit snapshots and review them as part of your regular code review process. This means treating snapshots as you would any other type of test or code in your project. + +Ensure that your snapshots are readable by keeping them focused, short, and by using tools that enforce these stylistic conventions. + +As mentioned previously, Jest uses [`pretty-format`](https://yarnpkg.com/en/package/pretty-format) to make snapshots human-readable, but you may find it useful to introduce additional tools, like [`eslint-plugin-jest`](https://yarnpkg.com/en/package/eslint-plugin-jest) with its [`no-large-snapshots`](https://github.com/jest-community/eslint-plugin-jest/blob/master/docs/rules/no-large-snapshots.md) option, or [`snapshot-diff`](https://yarnpkg.com/en/package/snapshot-diff) with its component snapshot comparison feature, to promote committing short, focused assertions. + +The goal is to make it easy to review snapshots in pull requests, and fight against the habit of simply regenerating snapshots when test suites fail instead of examining the root causes of their failure. + +### 2. Tests should be deterministic + +Your tests should be deterministic. Running the same tests multiple times on a component that has not changed should produce the same results every time. You're responsible for making sure your generated snapshots do not include platform specific or other non-deterministic data. + +For example, if you have a [Clock](https://github.com/facebook/jest/blob/master/examples/snapshot/Clock.react.js) component that uses `Date.now()`, the snapshot generated from this component will be different every time the test case is run. In this case we can [mock the Date.now() method](MockFunctions.md) to return a consistent value every time the test is run: + +```js +Date.now = jest.fn(() => 1482363367071); +``` + +Now, every time the snapshot test case runs, `Date.now()` will return `1482363367071` consistently. This will result in the same snapshot being generated for this component regardless of when the test is run. + +### 3. Use descriptive snapshot names + +Always strive to use descriptive test and/or snapshot names for snapshots. The best names describe the expected snapshot content. This makes it easier for reviewers to verify the snapshots during review, and for anyone to know whether or not an outdated snapshot is the correct behavior before updating. + +For example, compare: + +```js +exports[` should handle some test case`] = `null`; + +exports[` should handle some other test case`] = ` +
+ Alan Turing +
+`; +``` + +To: + +```js +exports[` should render null`] = `null`; + +exports[` should render Alan Turing`] = ` +
+ Alan Turing +
+`; +``` + +Since the later describes exactly what's expected in the output, it's easy to see when it's wrong: + +```js +exports[` should render null`] = ` +
+ Alan Turing +
+`; + +exports[` should render Alan Turing`] = `null`; +``` + +## Frequently Asked Questions + +### Are snapshots written automatically on Continuous Integration (CI) systems? + +No, as of Jest 20, snapshots in Jest are not automatically written when Jest is run in a CI system without explicitly passing `--updateSnapshot`. It is expected that all snapshots are part of the code that is run on CI and since new snapshots automatically pass, they should not pass a test run on a CI system. It is recommended to always commit all snapshots and to keep them in version control. + +### Should snapshot files be committed? + +Yes, all snapshot files should be committed alongside the modules they are covering and their tests. They should be considered as part of a test, similar to the value of any other assertion in Jest. In fact, snapshots represent the state of the source modules at any given point in time. In this way, when the source modules are modified, Jest can tell what changed from the previous version. It can also provide a lot of additional context during code review in which reviewers can study your changes better. + +### Does snapshot testing only work with React components? + +[React](TutorialReact.md) and [React Native](TutorialReactNative.md) components are a good use case for snapshot testing. However, snapshots can capture any serializable value and should be used anytime the goal is testing whether the output is correct. The Jest repository contains many examples of testing the output of Jest itself, the output of Jest's assertion library as well as log messages from various parts of the Jest codebase. See an example of [snapshotting CLI output](https://github.com/facebook/jest/blob/master/e2e/__tests__/console.test.js) in the Jest repo. + +### What's the difference between snapshot testing and visual regression testing? + +Snapshot testing and visual regression testing are two distinct ways of testing UIs, and they serve different purposes. Visual regression testing tools take screenshots of web pages and compare the resulting images pixel by pixel. With Snapshot testing values are serialized, stored within text files and compared using a diff algorithm. There are different trade-offs to consider and we listed the reasons why snapshot testing was built in the [Jest blog](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html#why-snapshot-testing). + +### Does snapshot testing substitute unit testing? + +Snapshot testing is only one of more than 20 assertions that ship with Jest. The aim of snapshot testing is not to replace existing unit tests, but providing additional value and making testing painless. In some scenarios, snapshot testing can potentially remove the need for unit testing for a particular set of functionalities (e.g. React components), but they can work together as well. + +### What is the performance of snapshot testing regarding speed and size of the generated files? + +Jest has been rewritten with performance in mind, and snapshot testing is not an exception. Since snapshots are stored within text files, this way of testing is fast and reliable. Jest generates a new file for each test file that invokes the `toMatchSnapshot` matcher. The size of the snapshots is pretty small: For reference, the size of all snapshot files in the Jest codebase itself is less than 300 KB. + +### How do I resolve conflicts within snapshot files? + +Snapshot files must always represent the current state of the modules they are covering. Therefore, if you are merging two branches and encounter a conflict in the snapshot files, you can either resolve the conflict manually or to update the snapshot file by running Jest and inspecting the result. + +### Is it possible to apply test-driven development principles with snapshot testing? + +Although it is possible to write snapshot files manually, that is usually not approachable. Snapshots help figuring out whether the output of the modules covered by tests is changed, rather than giving guidance to design the code in the first place. + +### Does code coverage work with snapshots testing? + +Yes, just like with any other test. diff --git a/website/versioned_docs/version-23.3/WatchPlugins.md b/website/versioned_docs/version-23.3/WatchPlugins.md new file mode 100644 index 000000000000..c4a218ccdc91 --- /dev/null +++ b/website/versioned_docs/version-23.3/WatchPlugins.md @@ -0,0 +1,183 @@ +--- +id: version-23.3-watch-plugins +title: Watch Plugins +original_id: watch-plugins +--- + +The Jest watch plugin system provides a way to hook into specific parts of Jest and to define watch mode menu prompts that execute code on key press. Combined, these features allow you to develop interactive experiences custom for your workflow. + +## Watch Plugin Interface + +```javascript +class MyWatchPlugin { + // Add hooks to Jest lifecycle events + apply(jestHooks) {} + + // Get the prompt information for interactive plugins + getUsageInfo(globalConfig) {} + + // Executed when the key from `getUsageInfo` is input + run(globalConfig, updateConfigAndRun) {} +} +``` + +## Hooking into Jest + +To connect your watch plugin to Jest, add its path under `watchPlugins` in your Jest configuration: + +```javascript +// jest.config.js +module.exports = { + // ... + watchPlugins: ['path/to/yourWatchPlugin'], +}; +``` + +Custom watch plugins can add hooks to Jest events. These hooks can be added either with or without having an interactive key in the watch mode menu. + +### `apply(jestHooks)` + +Jest hooks can be attached by implementing the `apply` method. This method receives a `jestHooks` argument that allows the plugin to hook into specific parts of the lifecycle of a test run. + +```javascript +class MyWatchPlugin { + apply(jestHooks) {} +} +``` + +Below are the hooks available in Jest. + +#### `jestHooks.shouldRunTestSuite(testPath)` + +Returns a boolean (or `Promise`) for handling asynchronous operations) to specify if a test should be run or not. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.shouldRunTestSuite(testPath => { + return testPath.includes('my-keyword'); + }); + + // or a promise + jestHooks.shouldRunTestSuite(testPath => { + return Promise.resolve(testPath.includes('my-keyword')); + }); + } +} +``` + +#### `jestHooks.onTestRunComplete(results)` + +Gets called at the end of every test run. It has the test results as an argument. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.onTestRunComplete(results => { + this._hasSnapshotFailure = results.snapshot.failure; + }); + } +} +``` + +#### `jestHooks.onFileChange({projects})` + +Gets called whenever there is a change in the file system + +- `projects: Array`: Includes all the test paths that Jest is watching. + +For example: + +```javascript +class MyWatchPlugin { + apply(jestHooks) { + jestHooks.onFileChange(({projects}) => { + this._projects = projects; + }); + } +} +``` + +## Watch Menu Integration + +Custom watch plugins can also add or override functionality to the watch menu by specifying a key/prompt pair in `getUsageInfo` method and a `run` method for the execution of the key. + +### `getUsageInfo(globalConfig)` + +To add a key to the watch menu, implement the `getUsageInfo` method, returning a key and the prompt: + +```javascript +class MyWatchPlugin { + getUsageInfo(globalConfig) { + return { + key: 's', + prompt: 'do something', + }; + } +} +``` + +This will add a line in the watch mode menu _(`› Press s to do something.`)_ + +```text +Watch Usage + › Press p to filter by a filename regex pattern. + › Press t to filter by a test name regex pattern. + › Press q to quit watch mode. + › Press s to do something. // <-- This is our plugin + › Press Enter to trigger a test run. +``` + +**Note**: If the key for your plugin already exists as a default key, your plugin will override that key. + +### `run(globalConfig, updateConfigAndRun)` + +To handle key press events from the key returned by `getUsageInfo`, you can implement the `run` method. This method returns a `Promise` that can be resolved when the plugin wants to return control to Jest. The `boolean` specifies if Jest should rerun the tests after it gets the control back. + +- `globalConfig`: A representation of Jest's current global configuration +- `updateConfigAndRun`: Allows you to trigger a test run while the interactive plugin is running. + +```javascript +class MyWatchPlugin { + run(globalConfig, updateConfigAndRun) { + // do something. + } +} +``` + +## Customization + +Plugins can be customized via your Jest configuration. + +```javascript +// jest.config.js +module.exports = { + // ... + watchPlugins: [ + [ + 'path/to/yourWatchPlugin', + { + key: 'k', // <- your custom key + prompt: 'show a custom prompt', + }, + ], + ], +}; +``` + +Recommended config names: + +- `key`: Modifies the plugin key. +- `prompt`: Allows user to customize the text in the plugin prompt. + +If the user provided a custom configuration, it will be passed as an argument to the plugin constructor. + +```javascript +class MyWatchPlugin { + constructor({config}) {} +} +``` diff --git a/website/versions.json b/website/versions.json index edbc70ffaaed..3e8fd743a724 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,4 +1,7 @@ [ + "23.3", + "23.2", + "23.1", "23.0", "22.4", "22.3", From e3f98a29ca6952446a5caf845dedc891e67ff311 Mon Sep 17 00:00:00 2001 From: rickhanlonii Date: Wed, 4 Jul 2018 15:36:09 -0400 Subject: [PATCH 2/3] Lint md, update changelog --- CHANGELOG.md | 1 + .../version-23.1/Configuration.md | 28 +++++------ .../versioned_docs/version-23.1/ExpectAPI.md | 18 +++---- .../version-23.1/JestObjectAPI.md | 48 +++++++++---------- .../version-23.1/WatchPlugins.md | 6 +-- 5 files changed, 51 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 009903b186cb..d5083ca80000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - `[website]` Switch domain to https://jestjs.io ([#6549](https://github.com/facebook/jest/pull/6549)) - `[tests]` Improve stability of `yarn test` on Windows ([#6534](https://github.com/facebook/jest/pull/6534)) - `[*]` Transpile object shorthand into Node 4 compatible syntax ([#6582](https://github.com/facebook/jest/pull/6582)) +- `[docs]` Add docs for 23.1, 23.2, and 23.3 ([#6623](https://github.com/facebook/jest/pull/6623)) ## 23.2.0 diff --git a/website/versioned_docs/version-23.1/Configuration.md b/website/versioned_docs/version-23.1/Configuration.md index 8557dc3aedcd..f165873776d6 100644 --- a/website/versioned_docs/version-23.1/Configuration.md +++ b/website/versioned_docs/version-23.1/Configuration.md @@ -235,10 +235,10 @@ For example, with the following configuration: 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`). +- 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] @@ -376,12 +376,12 @@ 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. +- `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] @@ -567,10 +567,10 @@ 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) +- [`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: diff --git a/website/versioned_docs/version-23.1/ExpectAPI.md b/website/versioned_docs/version-23.1/ExpectAPI.md index 6575f1280195..64a3d5c1f3b7 100644 --- a/website/versioned_docs/version-23.1/ExpectAPI.md +++ b/website/versioned_docs/version-23.1/ExpectAPI.md @@ -191,8 +191,8 @@ test('randocall calls its callback with a number', () => { You can use it instead of a literal value: -* in `toEqual` or `toBeCalledWith` -* to match a property in `objectContaining` or `toMatchObject` +- in `toEqual` or `toBeCalledWith` +- to match a property in `objectContaining` or `toMatchObject` ```js describe('arrayContaining', () => { @@ -359,9 +359,9 @@ test('onPress gets called with the right thing', () => { 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` +- 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`. @@ -399,8 +399,8 @@ expect.addSnapshotSerializer(serializer); 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). +- 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. @@ -1038,8 +1038,8 @@ Use `.toStrictEqual` to test that objects have the same types as well as structu Differences from `.toEqual`: -* Keys with `undefined` properties are checked. e.g. `{a: undefined, b: 2}` does not match `{b: 2}` when using `.toStrictEqual`. -* Object types are checked to be equal. e.g. A class instance with fields `a` and `b` will not equal a literal object with fields `a` and `b`. +- Keys with `undefined` properties are checked. e.g. `{a: undefined, b: 2}` does not match `{b: 2}` when using `.toStrictEqual`. +- Object types are checked to be equal. e.g. A class instance with fields `a` and `b` will not equal a literal object with fields `a` and `b`. ```js class LaCroix { diff --git a/website/versioned_docs/version-23.1/JestObjectAPI.md b/website/versioned_docs/version-23.1/JestObjectAPI.md index d55ae168dfc9..b5a2538f8aae 100644 --- a/website/versioned_docs/version-23.1/JestObjectAPI.md +++ b/website/versioned_docs/version-23.1/JestObjectAPI.md @@ -8,30 +8,30 @@ The `jest` object is automatically in scope within every test file. The methods ## 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) +- [`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) --- diff --git a/website/versioned_docs/version-23.1/WatchPlugins.md b/website/versioned_docs/version-23.1/WatchPlugins.md index c346cc04f5bd..85d365d4095d 100644 --- a/website/versioned_docs/version-23.1/WatchPlugins.md +++ b/website/versioned_docs/version-23.1/WatchPlugins.md @@ -78,7 +78,7 @@ class MyWatchPlugin { Gets called whenever there is a change in the file system -* `projects: Array`: Includes all the test paths that Jest is watching. +- `projects: Array`: Includes all the test paths that Jest is watching. For example: @@ -128,8 +128,8 @@ Watch Usage To handle key press events from the key returned by `getUsageInfo`, you can implement the `run` method. This method returns a `Promise` that can be resolved when the plugin wants to return control to Jest. The `boolean` specifies if Jest should rerun the tests after it gets the control back. -* `globalConfig`: A representation of Jest's current global configuration -* `updateConfigAndRun`: Allows you to trigger a test run while the interactive plugin is running. +- `globalConfig`: A representation of Jest's current global configuration +- `updateConfigAndRun`: Allows you to trigger a test run while the interactive plugin is running. ```javascript class MyWatchPlugin { From 43524cd3e1d3a0542ff1112a1c837547947891e1 Mon Sep 17 00:00:00 2001 From: rickhanlonii Date: Thu, 5 Jul 2018 10:11:11 -0400 Subject: [PATCH 3/3] Bump search version --- website/siteConfig.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/siteConfig.js b/website/siteConfig.js index 5e98baa70183..1c623b660eb4 100644 --- a/website/siteConfig.js +++ b/website/siteConfig.js @@ -114,7 +114,7 @@ const siteConfig = { apiKey: process.env.ALGOLIA_JEST_API_KEY, indexName: 'jest', algoliaOptions: { - facetFilters: ['language:LANGUAGE', 'version:23.0'], + facetFilters: ['language:LANGUAGE', 'version:23.3'], }, }, gaTrackingId: 'UA-44373548-17',