Chai OpenAPI レスポンスバリデーター
Chaiを使って、HTTPレスポンスがOpenAPI仕様を満たしていることをアサートします。
問題 😕
サーバーの挙動がAPIドキュメントと一致しない場合、サーバー、ドキュメント、またはその両方を修正する必要があります。早く知るほど良いでしょう。
解決策 😄
このプラグインを使用すると、サーバーの挙動とドキュメントが一致するかどうかを自動的にテストできます。 REST APIを文書化するためのOpenAPI標準をサポートするために、Chaiアサーションライブラリを拡張します。 JavaScriptテストでは、expect(responseObject).to.satisfyApiSpec
とアサートするだけです。
機能
- HTTPレスポンスのステータスとボディがOpenAPI仕様に一致することを検証します (例を参照)
- OpenAPI仕様で定義されたスキーマに対してオブジェクトを検証します (例を参照)
- OpenAPI仕様をテストで一度だけロードします(ファイルパスまたはオブジェクトからロード)
- OpenAPI 2と3をサポート
- YAMLおよびJSON形式のOpenAPI仕様をサポート
- レスポンス定義で
$ref
をサポート (例:$ref: '#/definitions/ComponentType/ComponentName'
) - OpenAPI仕様が無効な場合に通知
axios
、request-promise
、supertest
、superagent
、およびchai-http
からのレスポンスをサポート- Mochaおよびその他のテストランナーで使用
貢献 ✨
貢献するためにここに来てくれたのなら、ありがとうございます! 開始するには、貢献に関するドキュメントをご覧ください。
インストール
npm install --save-dev chai-openapi-response-validator
yarn add --dev chai-openapi-response-validator
インポート
ES6 / TypeScript
import chaiResponseValidator from 'chai-openapi-response-validator';
CommonJS / JavaScript
const chaiResponseValidator = require('chai-openapi-response-validator').default;
使用法
APIテストでは、HTTPレスポンスのステータスとボディをOpenAPI仕様に対して検証します。
1. テストを書きます
// Set up Chai
import chai from 'chai';
const expect = chai.expect;
// Import this plugin
import chaiResponseValidator from 'chai-openapi-response-validator';
// Load an OpenAPI file (YAML or JSON) into this plugin
chai.use(chaiResponseValidator('path/to/openapi.yml'));
// Write your test (e.g. using Mocha)
describe('GET /example/endpoint', () => {
it('should satisfy OpenAPI spec', async () => {
// Get an HTTP response from your server (e.g. using axios)
const res = await axios.get('https://:3000/example/endpoint');
expect(res.status).to.equal(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).to.satisfyApiSpec;
});
});
2. OpenAPI仕様を記述します(path/to/openapi.yml
に保存します)。
openapi: 3.0.0
info:
title: Example API
version: 1.0.0
paths:
/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. テストを実行して、サーバーの応答をOpenAPI仕様に対して検証します。
レスポンスステータスとボディがopenapi.yml
を満たしている場合、アサーションは成功します
// Response includes:
{
status: 200,
body: {
stringProperty: 'string',
integerProperty: 123,
},
};
レスポンスボディが無効な場合、アサーションは失敗します
// Response includes:
{
status: 200,
body: {
stringProperty: 'string',
integerProperty: 'invalid (should be an integer)',
},
};
テスト失敗時の出力
AssertionError: expected res to satisfy API spec
expected res to satisfy the '200' response defined for endpoint 'GET /example/endpoint' in your API spec
res did not satisfy it because: integerProperty should be integer
res 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'
}
}
}
},
}
ユニットテストでは、オブジェクトをOpenAPI仕様で定義されたスキーマに対して検証します。
1. テストを書きます
// Set up Chai
import chai from 'chai';
const expect = chai.expect;
// Import this plugin and the function you want to test
import chaiResponseValidator from 'chai-openapi-response-validator';
import { functionToTest } from 'path/to/your/code';
// Load an OpenAPI file (YAML or JSON) into this plugin
chai.use(chaiResponseValidator('path/to/openapi.yml'));
// Write your test (e.g. using Mocha)
describe('functionToTest()', () => {
it('should satisfy OpenAPI spec', async () => {
// Assert that the function returns a value satisfying a schema defined in your OpenAPI spec
expect(functionToTest()).to.satisfySchemaInApiSpec('ExampleSchemaObject');
});
});
2. OpenAPI仕様を記述します(path/to/openapi.yml
に保存します)。
openapi: 3.0.0
info:
title: Example API
version: 1.0.0
paths:
/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. テストを実行して、オブジェクトをOpenAPI仕様に対して検証します。
オブジェクトがスキーマExampleSchemaObject
を満たしている場合、アサーションは成功します
// object includes:
{
stringProperty: 'string',
integerProperty: 123,
};
オブジェクトがスキーマExampleSchemaObject
を満たしていない場合、アサーションは失敗します
// object includes:
{
stringProperty: 123,
integerProperty: 123,
};
テスト失敗時の出力
AssertionError: expected object to satisfy schema 'ExampleSchemaObject' defined in API spec:
object 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'
}
}
}
OpenAPI仕様のロード(3つの異なる方法)
1. 絶対ファイルパスから(上記参照)
2. オブジェクトから
// Set up Chai
import chai from 'chai';
const expect = chai.expect;
// Import this plugin
import chaiResponseValidator from 'chai-openapi-response-validator';
// Get an object representing your OpenAPI spec
const 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
chai.use(chaiResponseValidator(openApiSpec));
// Write your test (e.g. using Mocha)
describe('GET /example/endpoint', () => {
it('should satisfy OpenAPI spec', async () => {
// Get an HTTP response from your server (e.g. using axios)
const res = await axios.get('https://:3000/example/endpoint');
expect(res.status).to.equal(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).to.satisfyApiSpec;
});
});
3. Webエンドポイントから
// Set up Chai
import chai from 'chai';
const expect = chai.expect;
// Import this plugin and an HTTP client (e.g. axios)
import chaiResponseValidator from 'chai-openapi-response-validator';
import axios from 'axios';
// Write your test (e.g. using Mocha)
describe('GET /example/endpoint', () => {
// Load your OpenAPI spec from a web endpoint
before(async () => {
const response = await axios.get('url/to/openapi/spec');
const openApiSpec = response.data; // e.g. { openapi: '3.0.0', <etc> };
chai.use(chaiResponseValidator(openApiSpec));
});
it('should satisfy OpenAPI spec', async () => {
// Get an HTTP response from your server (e.g. using axios)
const res = await axios.get('https://:3000/example/endpoint');
expect(res.status).to.equal(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).to.satisfyApiSpec;
});
});