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 的請求。

在建構時,您會獲得一個可鏈式 API,讓您指定要調用的 HTTP VERB 請求 (get、post 等)。

應用程式 / 伺服器

您可以使用函數 (例如 express 或 connect 應用程式) 或 node.js http(s) 伺服器作為請求的基礎。如果伺服器未執行,chai-http 將為指定的測試找到合適的監聽連接埠。

注意:此功能僅在 Node.js 上支援,不適用於網頁瀏覽器。

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

app 傳遞給 request 時,它會自動開啟伺服器以接收傳入的請求 (透過呼叫 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('http://localhost:8080')
  .get('/')

設定請求

使用指定的 VERB (get、post 等) 建立請求後,您會鏈式使用這些額外的方法來建立您的請求。

方法 目的
.set(key, value) 設定請求標頭
.send(data) 設定請求資料 (預設類型為 JSON)
.type(dataType) 變更從 .send() 方法傳送的資料類型 (xml、form 等)
.attach(field, file, attachment) 附加檔案
.auth(username, password) 為基本驗證新增驗證標頭
.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('http://localhost: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('http://localhost: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}_ 標頭值 (選用)

斷言 ResponseRequest 物件具有標頭。如果提供值,則會斷言與值相等。您也可以傳遞正規表示式來檢查。

注意:在網頁瀏覽器中執行時,同源原則只允許 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

斷言 ResponseRequest 物件具有標頭。

注意:在網頁瀏覽器中執行時,同源原則只允許 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

斷言 ResponseRequest 物件具有指定的 content-type。

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

.charset

斷言 ResponseRequest 物件具有指定的字元集。

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} 參數值

斷言 RequestResponse 物件具有帶有指定鍵的 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 和外掛程式發布

授權

(The MIT License)

Copyright (c) Jake Luer jake@alogicalparadox.com

特此免費授予任何取得本軟體及相關文件檔案(以下稱「軟體」)副本的人員,不受限制地處理本軟體之權利,包括但不限於使用、複製、修改、合併、出版、散布、再授權和/或銷售軟體副本,並允許軟體被提供給的人員,但需符合下列條件:

上述版權聲明和本許可聲明應包含在所有副本或軟體的重要部分中。

本軟體依「現狀」提供,不提供任何明示或暗示的擔保,包括但不限於適銷性、適用於特定目的及未侵權的擔保。在任何情況下,作者或版權持有人均不對任何索賠、損害或其他責任負責,無論該責任是因契約、侵權或其他行為而產生,並由本軟體或本軟體的使用或其他交易引起或與之相關。