Chai HTTP 建置狀態 semantic-release

使用 Chai 斷言進行 HTTP 整合測試。

特色

  • 整合測試請求組成
  • 測試 http 應用程式或外部服務
  • 常見 http 任務的斷言
  • chai expectshould 介面

安裝

這是 Chai 斷言函式庫的附加外掛程式。透過 npm 安裝。

npm install chai-http

外掛程式

像使用其他 Chai 外掛程式一樣使用此外掛程式。

var chai = require('chai')
  , chaiHttp = require('chai-http');

chai.use(chaiHttp);

若要在網頁上使用 Chai HTTP,只需包含 dist/chai-http.js 檔案即可

<script src="chai.js"></script>
<script src="chai-http.js"></script>
<script>
  chai.use(chaiHttp);
</script>

整合測試

Chai HTTP 提供透過 superagent 進行即時整合測試的介面。為此,您必須首先建構對應用程式或 URL 的請求。

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

應用程式 / 伺服器

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

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

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

app 傳遞至 request 時;它會自動開啟伺服器以接收傳入的請求(透過呼叫 listen()),並且在發出請求後,伺服器會自動關閉(透過呼叫 .close())。如果您想要保持伺服器開啟,可能是因為您要發出多個請求,則必須在 .request() 之後呼叫 .keepOpen(),並手動關閉伺服器

var requester = chai.request(app).keepOpen()

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

URL

您也可以使用基本 URL 作為請求的基礎。

chai.request('https://#: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(app)
  .put('/user/me')
  .set('Content-Type', 'application/json')
  .send({ password: '123', confirmPassword: '123' })

.send()

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

.type()

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

.attach()

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

.auth()

// Authenticate with Basic authentication
chai.request(app)
  .get('/protected')
  .auth('user', 'pass')

.query()

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

處理回應 - 傳統方式

在以下範例中,我們使用 Chai 的 Expect 斷言函式庫

var expect = chai.expect;

若要發出請求並對其回應進行斷言,可以使用 end 方法

chai.request(app)
  .put('/user/me')
  .send({ password: '123', confirmPassword: '123' })
  .end(function (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('https://#:8080')
  .get('/')
  .end(function(err, res) {
    expect(res).to.have.status(123);
    done();                               // <= Call done to signal callback end
  });
});

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

傳入 done 時,Mocha 會等待直到呼叫 done(),或直到 逾時到期。在發出完成信號時,done 也會接受錯誤參數。

處理回應 - Promise

如果 Promise 可用,request() 會成為一個具備 Promise 功能的函式庫 - 並且可以鏈接 thens

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

注意:Node.js 0.10.x 版和某些較舊的網頁瀏覽器沒有原生 Promise 支援。您可以使用任何符合規格的函式庫,例如

// Add promise support if this does not exist natively.
if (!global.Promise) {
  global.Promise = require('q');
}
var chai = require('chai');
chai.use(require('chai-http'));

在每次請求中保留 Cookie

有時候,您需要保留來自一個請求的 Cookie,並將其與下一個請求一起傳送(例如,當您想要使用第一個請求登入,然後稍後存取僅限驗證的資源時)。為此,可以使用 .request.agent()

// Log in
var agent = chai.request.agent(app)
agent
  .post('/session')
  .send({ username: 'me', password: '123' })
  .then(function (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(function (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 物件具有指定的內容類型。

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 使用外掛程式發佈的

授權條款

(MIT 授權條款)

版權所有 (c) Jake Luer jake@alogicalparadox.com

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

上述版權聲明和本授權聲明應包含在本軟體的所有副本或實質部分中。

本軟體依「現狀」提供,不帶任何明示或暗示的擔保,包括但不限於適銷性、特定用途之適用性和不侵權的擔保。在任何情況下,作者或版權持有人均不對任何索賠、損害或其他責任負責,無論是在合約訴訟、侵權訴訟或其他訴訟中,因軟體或軟體的使用或其他處理方式而引起或與之相關。