Chai HTTP

使用 Chai 斷言進行 HTTP 整合測試。
功能
- 整合測試請求組成
- 測試 HTTP 應用程式或外部服務
- 常用 HTTP 任務的斷言
- chai
expect
和should
介面
安裝
這是 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 模組為 expect
和 should
介面提供許多斷言。
.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
物件具有指定的 content-type。
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');
.cookie
- @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
和外掛程式發布
commit-analyzer
從提交訊息中判斷下一個版本。release-notes-generator
在總結發布changelog
更新 CHANGELOG.md 檔案。github
發布 GitHub 版本。git
提交發布資產。npm
發布到 npm。
授權
(The MIT License)
Copyright (c) Jake Luer jake@alogicalparadox.com
特此免費授予任何取得本軟體及相關文件檔案(以下稱「軟體」)副本的人員,不受限制地處理本軟體之權利,包括但不限於使用、複製、修改、合併、出版、散布、再授權和/或銷售軟體副本,並允許軟體被提供給的人員,但需符合下列條件:
上述版權聲明和本許可聲明應包含在所有副本或軟體的重要部分中。
本軟體依「現狀」提供,不提供任何明示或暗示的擔保,包括但不限於適銷性、適用於特定目的及未侵權的擔保。在任何情況下,作者或版權持有人均不對任何索賠、損害或其他責任負責,無論該責任是因契約、侵權或其他行為而產生,並由本軟體或本軟體的使用或其他交易引起或與之相關。