jest-openapi
Additional Jest matchers for asserting that HTTP responses satisfy an OpenAPI spec.
Problem 😕
If your server's behaviour doesn't match your API documentation, then you need to correct your server, your documentation, or both. The sooner you know the better.
Solution 😄
This plugin lets you automatically test whether your server's behaviour and documentation match. It adds Jest matchers that support the OpenAPI standard for documenting REST APIs. In your JavaScript tests, you can simply assert expect(responseObject).toSatisfyApiSpec()
Features:
- Validates the status and body of HTTP responses against your OpenAPI spec (see example)
- Validates objects against schemas defined in your OpenAPI spec (see example)
- Load your OpenAPI spec just once in your tests (load from a filepath or object)
- Supports OpenAPI 2 and 3
- Supports OpenAPI specs in YAML and JSON formats
- Supports
$ref
in response definitions (i.e.$ref: '#/definitions/ComponentType/ComponentName'
) - Informs you if your OpenAPI spec is invalid
- Supports responses from
axios
,request-promise
,supertest
,superagent
, andchai-http
- Bundled with a TypeScript Declaration File for use in TypeScript projects
- Use in Jest, or use our sister package for Mocha and other test runners that support Chai
Contributing ✨
If you've come here to help contribute - thanks! Take a look at the contributing docs to get started.
Installation
With npm:
npm install --save-dev jest-openapi
Usage
In API tests, validate the status and body of HTTP responses against your OpenAPI spec:
1. Write a test:
// Import this pluginconst jestOpenAPI = ; // Load an OpenAPI file (YAML or JSON) into this plugin; // Write your test;
path/to/openapi.yml
):
2. Write an OpenAPI Spec (and save to openapi: 3.0.0info: title: Example API version: 1.0.0paths: /example: get: responses: 200: description: Response body should be an object with fields 'stringProperty' and 'integerProperty' content: application/json: schema: type: object required: - stringProperty - integerProperty properties: stringProperty: type: string integerProperty: type: integer
3. Run your test to validate your server's response against your OpenAPI spec:
openapi.yml
:
The assertion passes if the response status and body satisfy // Response includes: status: 200 body: stringProperty: 'string' integerProperty: 123 ;
The assertion fails if the response body is invalid:
// Response includes: status: 200 body: stringProperty: 'string' integerProperty: 'invalid (should be an integer)' ;
Output from test failure:
// Matches 'received' to a response defined in your API spec, then validates 'received' against it expected received to satisfy the '200' response defined for endpoint 'GET /example/endpoint' in your API specreceived did not satisfy it because: integerProperty should be integer received contained: body: stringProperty: 'string' integerProperty: 'invalid (should be an integer)' } The '200' response defined for endpoint 'GET /example/endpoint' in API spec: '200': description: 'Response body should be a string' content: 'application/json': schema: type: 'string'
In unit tests, validate objects against schemas defined in your OpenAPI spec:
1. Write a test:
// Import this pluginconst jestOpenAPI = ; // Load an OpenAPI file (YAML or JSON) into this plugin; // Write your test;
path/to/openapi.yml
):
2. Write an OpenAPI Spec (and save to openapi: 3.0.0info: title: Example API version: 1.0.0paths: /example: get: responses: 200: description: Response body should be an ExampleSchemaObject content: application/json: schema: '#/components/schemas/ExampleSchemaObject'components: schemas: ExampleSchemaObject: type: object required: - stringProperty - integerProperty properties: stringProperty: type: string integerProperty: type: integer
3. Run your test to validate your object against your OpenAPI spec:
ExampleSchemaObject
:
The assertion passes if the object satisfies the schema // object includes: stringProperty: 'string' integerProperty: 123;
ExampleSchemaObject
:
The assertion fails if the object does not satisfy the schema // object includes: stringProperty: 123 integerProperty: 123;
Output from test failure:
not // Matches 'received' to a schema defined in your API spec, then validates 'received' against it expected received to satisfy the 'StringSchema' schema defined in your API specobject did not satisfy it because: stringProperty should be string object was: stringProperty: 123 integerProperty: 123 } The 'ExampleSchemaObject' schema in API spec: type: 'object' required: 'stringProperty' 'integerProperty' properties: stringProperty: type: 'string' integerProperty: type: 'integer'
Loading your OpenAPI spec (3 different ways):
see above)
1. From an absolute filepath (2. From an object:
// Import this pluginconst jestOpenAPI = ; // Get an object representing your OpenAPI specconst openApiSpec = openapi: '3.0.0' info: title: 'Example API' version: '0.1.0' paths: '/example/endpoint': get: responses: 200: description: 'Response body should be a string' content: 'application/json': schema: type: 'string' ; // Load that OpenAPI object into this plugin; // Write your test;
3. From a web endpoint:
// Import this pluginconst jestOpenAPI = ; // Write your test;
Using this plugin in a TypeScript project
Installation
You don't need to npm install --save-dev @types/jest-openapi
because we bundle our TypeScript Definition file into this package.
Importing
- Make sure your
tsconfig.json
includes:
"compilerOptions": esModuleInterop: true
- Import like this:
;