Chai HTTP semantic-release NPM 版本

使用 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 上受支持,在 Web 浏览器中不受支持。

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('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.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}_ 头部值(可选)

断言一个 ResponseRequest 对象具有一个头。如果提供了一个值,则将断言等于该值。您也可以传递一个正则表达式进行检查。

注意:在 Web 浏览器中运行时,同源策略 仅允许 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 对象具有头。

注意:在 Web 浏览器中运行时,同源策略 仅允许 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 发布的,并使用以下插件

许可证

(麻省理工学院许可证)

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

特此授予任何人免费获得本软件和相关文档文件(“软件”)副本的权利,不受限制地处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,以及允许获得软件的人员这样做,但须符合以下条件:

以上版权声明和本许可声明应包含在所有软件副本或实质部分中。

软件按“原样”提供,不提供任何形式的明示或暗示担保,包括但不限于适销性、特定目的适用性和不侵权的担保。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任承担责任,无论是在合同、侵权行为或其他情况下,由软件或软件的使用或其他交易产生、引起或与之相关的。