Chai HTTP semantic-release NPM version

Chai アサーションを使用したHTTP統合テスト。

機能

  • 統合テストリクエストの構成
  • HTTPアプリケーションまたは外部サービスのテスト
  • 一般的なHTTPタスクのアサーション
  • Chai の expectshould インターフェース

インストール

これは、Chai アサーションライブラリ のアドオンプラグインです。npm を使用してインストールします。

npm install chai-http

プラグイン

他のChaiプラグインと同様に、このプラグインを使用します。

import chaiModule from "chai";
import chaiHttp from "chai-http";

const chai = chaiModule.use(chaiHttp);

ウェブページでChai HTTPを使用するには、現時点では最新のv4バージョンを使用してください。

統合テスト

Chai HTTPは、superagent を介したライブ統合テスト用のインターフェースを提供します。これを行うには、最初にアプリケーションまたはURLへのリクエストを構築する必要があります。

構築後、呼び出したいHTTP VERBリクエスト(get、postなど)を指定できるチェーン可能なAPIが提供されます。

アプリケーション/サーバー

リクエストの基礎として、関数(ExpressまたはConnectアプリなど)またはnode.jsのhttp(s)サーバーを使用できます。サーバーが実行されていない場合、chai-httpは指定されたテストでリスンする適切なポートを見つけます。

注記: この機能はNode.jsでのみサポートされており、ウェブブラウザではサポートされていません。

chai.request.execute(app)
  .get('/')

apprequest に渡す場合、着信リクエストに対してサーバーが自動的に開きます(listen() を呼び出すことによって)。リクエストが行われると、サーバーは自動的にシャットダウンされます(.close() を呼び出すことによって)。複数のリクエストを行う場合など、サーバーを継続的に開いておく場合は、.request() の後に .keepOpen() を呼び出し、サーバーを手動でシャットダウンする必要があります。

const requester = chai.request.Request(app).keepOpen()

Promise.all([
  requester.get('/a'),
  requester.get('/b'),
])
.then(responses => { /* ... */ })
.then(() => requester.close())

URL

リクエストの基礎として、基本URLを使用することもできます。

chai.request.execute('https://:8080')
  .get('/')

リクエストの設定

特定のVERB(get、postなど)でリクエストを作成したら、これらの追加メソッドをチェーンしてリクエストを作成します。

メソッド 目的
.set(key, value) リクエストヘッダーの設定
.send(data) リクエストデータの設定(デフォルトタイプはJSON)
.type(dataType) .send() メソッドから送信されるデータのタイプを変更します(xml、formなど)
.attach(field, file, attachment) ファイルの添付
.auth(username, password) Basic認証の認証ヘッダーの追加
.query(parmasObject) GETパラメータの追加

.set()

// Set a request header
chai.request.execute(app)
  .put('/user/me')
  .set('Content-Type', 'application/json')
  .send({ password: '123', confirmPassword: '123' })

.send()

// Send some JSON
chai.request.execute(app)
  .put('/user/me')
  .send({ password: '123', confirmPassword: '123' })

.type()

// Send some Form Data
chai.request.execute(app)
  .post('/user/me')
  .type('form')
  .send({
    '_method': 'put',
    'password': '123',
    'confirmPassword': '123'
  })

.attach()

// Attach a file
chai.request.execute(app)
  .post('/user/avatar')
  .attach('imageField', fs.readFileSync('avatar.png'), 'avatar.png')

.auth()

// Authenticate with Basic authentication
chai.request.execute(app)
  .get('/protected')
  .auth('user', 'pass')
  
// Authenticate with Bearer Token
chai.request.execute(app)
  .get('/protected')
  .auth(accessToken, { type: 'bearer' })  
  

.query()

// Chain some GET query parameters
chai.request.execute(app)
  .get('/search')
  .query({name: 'foo', limit: 10}) // /search?name=foo&limit=10

レスポンスの処理 - 従来の方法

以下の例では、ChaiのExpectアサーションライブラリを使用しています。

const { expect } = chai;

リクエストを行い、レスポンスをアサートするには、end メソッドを使用できます。

chai.request.execute(app)
  .put('/user/me')
  .send({ password: '123', confirmPassword: '123' })
  .end((err, res) => {
     expect(err).to.be.null;
     expect(res).to.have.status(200);
  });
注意点

end 関数にはコールバックが渡されるため、アサーションは非同期的に実行されます。したがって、コールバックが完了したことをテストフレームワークに通知するメカニズムを使用する必要があります。そうでなければ、アサーションがチェックされる前にテストが合格してしまいます。

たとえば、Mochaテストフレームワーク では、これはdone コールバック を使用して実現されます。これは、コールバックが完了し、アサーションを確認できることをシグナルします。

it('fails, as expected', function(done) { // <= Pass in done callback
  chai.request.execute('https://:8080')
  .get('/')
  .end((err, res) => {
    expect(res).to.have.status(123);
    done();                               // <= Call done to signal callback end
  });
});

it('succeeds silently!', () => {   // <= No done callback
  chai.request.execute('https://:8080')
  .get('/')
  .end((err, res) => {
    expect(res).to.have.status(123);    // <= Test completes before this runs
  });
});

done が渡されると、Mochaはdone() の呼び出しまで、またはタイムアウト が期限切れになるまで待機します。done は、完了時にエラーパラメータも受け入れます。

レスポンスの処理 - Promise

Promise が利用可能な場合、request() はPromise対応ライブラリになり、then のチェーンが可能になります。

chai.request.execute(app)
  .put('/user/me')
  .send({ password: '123', confirmPassword: '123' })
  .then((res) => {
     expect(res).to.have.status(200);
  })
  .catch((err) => {
     throw err;
  });

各リクエストでのCookieの保持

リクエストからCookieを保持し、次のリクエストで送信する必要がある場合があります(たとえば、最初のリクエストでログインし、後で認証のみのリソースにアクセスする場合など)。そのため、.request.agent() が利用可能です。

// Log in
const agent = chai.request.agent(app)
agent
  .post('/session')
  .send({ username: 'me', password: '123' })
  .then((res) => {
    expect(res).to.have.cookie('sessionid');
    // The `agent` now has the sessionid cookie saved, and will send it
    // back to the server in the next request:
    return agent.get('/user/me')
      .then((res) => {
         expect(res).to.have.status(200);
      });
  });

注記: chai.request.agent(app) で開始されたサーバーは、テスト後も自動的に閉じません。プログラムが終了するように、テスト後に agent.close() を呼び出す必要があります。

アサーション

Chai HTTPモジュールは、expectshould インターフェースに多くのアサーションを提供します。

.status (code)

  • @param {Number} ステータス番号

レスポンスが指定されたステータスを持つことをアサートします。

expect(res).to.have.status(200);

.header (key[, value])

  • @param {String} ヘッダーキー(大文字小文字を区別しない)
  • @param _{String} RegExp}_ ヘッダー値(オプション)

Response または Request オブジェクトにヘッダーがあることをアサートします。値が提供されている場合、値との等価性がアサートされます。正規表現を渡してチェックすることもできます。

注記: ウェブブラウザで実行している場合、同一オリジンポリシー により、Chai HTTPは特定のヘッダーのみ を読み取ることができ、アサーションが失敗する可能性があります。

expect(req).to.have.header('x-api-key');
expect(req).to.have.header('content-type', 'text/plain');
expect(req).to.have.header('content-type', /^text/);

.headers

Response または Request オブジェクトにヘッダーがあることをアサートします。

注記: ウェブブラウザで実行している場合、同一オリジンポリシー により、Chai HTTPは特定のヘッダーのみ を読み取ることができ、アサーションが失敗する可能性があります。

expect(req).to.have.headers;

.ip

文字列が有効なIPアドレスを表すことをアサートします。

expect('127.0.0.1').to.be.an.ip;
expect('2001:0db8:85a3:0000:0000:8a2e:0370:7334').to.be.an.ip;

.json / .text / .html

Response または Request オブジェクトに指定されたコンテンツタイプがあることをアサートします。

expect(req).to.be.json;
expect(req).to.be.html;
expect(req).to.be.text;

.charset

Response または Request オブジェクトに指定された文字セットがあることをアサートします。

expect(req).to.have.charset('utf-8');

.redirect

Response オブジェクトにリダイレクトステータスコードがあることをアサートします。

expect(res).to.redirect;
expect(res).to.not.redirect;

.redirectTo

  • @param _{String} RegExp}_ 位置URL

Response オブジェクトが指定された場所にリダイレクトすることをアサートします。

expect(res).to.redirectTo('http://example.com');
expect(res).to.redirectTo(/^\/search\/results\?orderBy=desc$/);

.param

  • @param {String} パラメータ名
  • @param {String} パラメータ値

Request オブジェクトに、指定されたキーを持つクエリ文字列パラメータがあり(オプションで)、値に等しいことをアサートします。

expect(req).to.have.param('orderby');
expect(req).to.have.param('orderby', 'date');
expect(req).to.not.have.param('limit');
  • @param {String} パラメータ名
  • @param {String} パラメータ値

Request または Response オブジェクトに、指定されたキーを持つCookieヘッダーがあり(オプションで)、値に等しいことをアサートします。

expect(req).to.have.cookie('session_id');
expect(req).to.have.cookie('session_id', '1234');
expect(req).to.not.have.cookie('PHPSESSID');
expect(res).to.have.cookie('session_id');
expect(res).to.have.cookie('session_id', '1234');
expect(res).to.not.have.cookie('PHPSESSID');

リリース

chai-http は、semantic-release を使用して、次のプラグインでリリースされます。

ライセンス

(MITライセンス)

Copyright (c) Jake Luer jake@alogicalparadox.com

このソフトウェアおよび関連するドキュメントファイル(以下「ソフトウェア」といいます)のコピーを取得するすべての人に、使用、複製、変更、マージ、公開、配布、サブライセンス、および/またはソフトウェアのコピーの販売を含む、制限なくソフトウェアを処理する権利を、無料で許可します。ソフトウェアが提供される者に、以下の条件に従ってそうすることを許可します。

上記の著作権表示とこの許可表示は、ソフトウェアのすべての複製または実質的な部分に含まれるものとします。

ソフトウェアは、「現状のまま」提供され、明示的または黙示的を問わず、商品性、特定目的への適合性、および非侵害に関する保証を含むがこれらに限定されない、いかなる種類の保証も行いません。いかなる場合においても、著作者または著作権保有者は、ソフトウェアまたはソフトウェアの使用またはその他の取引に関連して生じる請求、損害、またはその他の責任について、契約、不法行為、またはその他の責任について責任を負いません。