测试

测试是开发一个应用当中不可或缺的一部分。
Fastify 并没有提供开箱即用的测试框架,你需要自己搭建单元测试环境。

所需的模块:

  • Tap: 一个优秀的测试框架,包含一个很好的断言库和很多实用方法。
  • Request: 一个优秀的客户端 Http 库。
  • Minimist: 一个CLI解析器,用于从命令行运行服务器。
// server.js
const minimist = require('minimist')
const fastify = require('fastify')()

const options = {
  schema: {
    response: {
      200: {
        type: 'object',
        properties: {
          hello: { type: 'string' }
        }
      }
    }
  }
}

function start (opts, callback) {
  fastify.get('/', options, function (request, reply) {
    reply.send({ hello: 'world' })
  })

  fastify.listen(opts.port, function (err) {
    callback(err, fastify)
  })
}

// 以这种方式,您可以从CLI和所需的模块运行服务器
if (require.main === module) {
  // Run the server with:
  // $ node server.js -p 8080
  start(minimist(process.argv.slice(2), {
    integer: ['port'],
    alias: {
      port: 'p'
    },
    default: {
      port: 3000
    }
  }), (err, instance) => {
    if (err) throw err

    console.log(`server listening on ${instance.server.address().port}`)
  })
}

// 导出函数,启动服务。
// in this way inside the test files we can require and run it.
module.exports = { start }
// test.js
const t = require('tap')
const test = t.test
const request = require('request')
const server = require('./server')

// Run the server
server.start({ port: 0 }, (err, fastify) => {
  t.error(err)

  test('The server should start', t => {
    t.plan(4)
    // Perform the request
    request({
      method: 'GET',
      uri: `http://localhost:${fastify.server.address().port}`
    }, (err, response, body) => {
      // Unit test
      t.error(err)
      t.strictEqual(response.statusCode, 200)
      t.strictEqual(response.headers['content-length'], '' + body.length)
      t.deepEqual(JSON.parse(body), { hello: 'world' })
      fastify.close()
    })
  })
})

使用http注入进行测试

Fastify 支持伪 http 注入,感谢 light-my-request

使用 inject方法:

fastify.inject({
  method: String,
  url: String,
  payload: Object,
  headers: Object
}, response => {
  // your tests
})

使用promise:

fastify
  .inject({
    method: String,
    url: String,
    payload: Object,
    headers: Object
  })
  .then(response => {
    // your tests
  })

使用 async/await:

const res = await fastify.inject({ method: String, url: String, payload: Object, headers: Object })

Example:

// server.js
const minimist = require('minimist')
const fastify = require('fastify')()

const options = {
  schema: {
    response: {
      200: {
        type: 'object',
        properties: {
          hello: { type: 'string' }
        }
      }
    }
  }
}

fastify.get('/', options, function (request, reply) {
  reply.send({ hello: 'world' })
})

function start (opts, callback) {
  fastify.listen(opts.port, function (err) {
    callback(err, fastify)
  })
}

// In this way you can run the server both from the CLI and as a required module.
if (require.main === module) {
  // Run the server with:
  // $ node server.js -p 8080
  start(minimist(process.argv.slice(2), {
    integer: ['port'],
    alias: {
      port: 'p'
    },
    default: {
      port: 3000
    }
  }), (err, instance) => {
    if (err) throw err

    console.log(`server listening on ${instance.server.address().port}`)
  })
}

// note that now we are also exposing the fastify instance
module.exports = { start, fastify }
// test.js
const t = require('tap')
const test = t.test
const request = require('request')
const fastify = require('./server').fastify

test('GET `/` route', t => {
  t.plan(3)

  fastify.inject({
    method: 'GET',
    url: '/'
  }, res => {
    t.strictEqual(res.statusCode, 200)
    t.strictEqual(res.headers['content-length'], '' + body.length)
    t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
    // even if the server is not running (inject does not run the server)
    // at the end of your tests is highly recommended call `.close()`,
    // in this way you will close all the connections to external services
    fastify.close()
  })
})

results matching ""

    No results matching ""