使用 Chai 测试 RESTful API 的实用指南

在日常的前端开发中,测试是非常重要的一环。在开发过程中,我们经常与 RESTful API 打交道,对 API 进行测试也是必不可少的。Chai 是一个流行的 JavaScript 测试框架,本文将会介绍如何使用 Chai 进行 RESTful API 的测试,以及如何利用 Chai 的功能更加高效地编写测试用例。

安装 Chai

首先,我们需要安装 Chai。可以在命令行中使用以下命令进行安装:

npm install chai --save-dev

这会将 Chai 安装为开发依赖项,并将其添加到 package.json 文件中。

如果你使用的是 Mocha,Chai 会自动安装并作为其默认断言库。否则,你需要手动导入 Chai。可以在测试文件中添加以下代码:

const { expect } = require('chai');

发送 HTTP 请求

在测试 RESTful API 之前,我们需要发送 HTTP 请求。对于 Node.js,我们可以使用官方的 HTTP 模块。例如,以下代码将发送 GET 请求:

const http = require('http');

http.get('http://localhost:3000/api/v1/posts', (res) => {
  let data = '';

  res.on('data', (chunk) => {
    data += chunk;
  });

  res.on('end', () => {
    console.log(JSON.parse(data));
  });
}).on('error', (err) => {
  console.log(err);
});

如果你使用的是 Express,你可以使用 supertest 模块。以下是一个示例代码:

const request = require('supertest');
const app = require('../app');

describe('GET /api/v1/posts', () => {
  it('responds with JSON', (done) => {
    request(app)
      .get('/api/v1/posts')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200, done);
  });
});

使用 Chai 进行断言

发送请求之后,我们需要对返回的结果进行测试。使用 Chai 很方便,我们可以使用它提供的各种断言方法。例如,以下代码将测试响应是否包含正确数量的文章:

const { expect } = require('chai');
const http = require('http');

describe('GET /api/v1/posts', () => {
  it('returns all posts', (done) => {
    http.get('http://localhost:3000/api/v1/posts', (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        const posts = JSON.parse(data);
        expect(posts).to.have.lengthOf(3);
        done();
      });
    });
  });
});

Chai 提供了许多类似于 expect 的断言方法,例如 should 和 assert。它们之间的区别在于语法不同:expect 使用链式语法,should 和 assert 则需要将测试对象作为参数传递给它们的断言方法。

以下是使用 should 的示例代码:

const should = require('chai').should();
const http = require('http');

describe('GET /api/v1/posts', () => {
  it('returns all posts', (done) => {
    http.get('http://localhost:3000/api/v1/posts', (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        const posts = JSON.parse(data);
        posts.should.have.lengthOf(3);
        done();
      });
    });
  });
});

在使用 should 时,应该注意不要在非测试代码中使用它。这是因为 should 会改变对象的原型,可能会对代码带来一些意外的影响。

使用 Chai 的辅助函数

除了基本的断言方法之外,Chai 还提供了一些辅助方法,可以帮助我们编写更加高效的测试用例。

expect 和 should 的辅助方法

Chai 可以为 expect 和 should 提供许多方法,例如 deep 和 nested。以下是一个示例代码:

const { expect } = require('chai');
const http = require('http');

describe('GET /api/v1/posts', () => {
  it('has the correct structure', (done) => {
    http.get('http://localhost:3000/api/v1/posts', (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        const posts = JSON.parse(data);

        expect(posts).to.be.an('array').that.has.lengthOf(3);

        const post = posts[0];

        expect(post).to.be.an('object').that.has.all.keys('id', 'title', 'body', 'created_at', 'updated_at');
        expect(post.id).to.be.a('number');
        expect(post.title).to.be.a('string');
        expect(post.body).to.be.a('string');
        expect(post.created_at).to.be.a('string');
        expect(post.updated_at).to.be.a('string');

        done();
      });
    });
  });
});

describe('GET /api/v1/posts/:id', () => {
  it('returns a single post', (done) => {
    http.get('http://localhost:3000/api/v1/posts/1', (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        const post = JSON.parse(data);

        expect(post).to.be.an('object').that.has.all.keys('id', 'title', 'body', 'created_at', 'updated_at');
        expect(post.id).to.be.a('number');
        expect(post.title).to.be.a('string');
        expect(post.body).to.be.a('string');
        expect(post.created_at).to.be.a('string');
        expect(post.updated_at).to.be.a('string');

        done();
      });
    });
  });
});

可以看到,在这个测试用例中,我们使用了 expect 和 should 的许多方法。这些方法使我们的测试用例更加简洁和易读。

使用 Chai 的插件

除了默认的断言方法之外,Chai 还可以使用插件提供更多的功能。例如,chai-http 插件可以让我们更加方便地发送 HTTP 请求。

以下是使用 chai-http 的示例代码:

const chai = require('chai');
const chaiHttp = require('chai-http');
const app = require('../app');

chai.use(chaiHttp);

const { expect } = chai;

describe('GET /api/v1/posts', () => {
  it('returns all posts', (done) => {
    chai.request(app)
      .get('/api/v1/posts')
      .end((err, res) => {
        expect(res).to.have.status(200);
        expect(res.body).to.be.an('array').that.has.lengthOf(3);
        done();
      });
  });
});

describe('GET /api/v1/posts/:id', () => {
  it('returns a single post', (done) => {
    chai.request(app)
      .get('/api/v1/posts/1')
      .end((err, res) => {
        expect(res).to.have.status(200);
        expect(res.body).to.be.an('object').that.has.all.keys('id', 'title', 'body', 'created_at', 'updated_at');
        expect(res.body.id).to.be.a('number');
        expect(res.body.title).to.be.a('string');
        expect(res.body.body).to.be.a('string');
        expect(res.body.created_at).to.be.a('string');
        expect(res.body.updated_at).to.be.a('string');
        done();
      });
  });
});

可以看到,使用 chai-http 插件之后,我们可以更加方便地发送 HTTP 请求,并且可以更加简洁地编写测试用例。

总结

在本文中,我们介绍了如何使用 Chai 测试 RESTful API,并且演示了如何使用 Chai 的辅助方法和插件编写更加高效的测试用例。测试是前端开发过程中非常重要的一部分,通过使用 Chai,我们可以更加轻松地编写和执行测试用例,确保我们的代码

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65953ba3eb4cecbf2d96f21d


纠错反馈