如何在单元测试中模拟节点数据库连接?

时间:2017-12-19 14:13:53

标签: node.js unit-testing oracledb oracledb-npm

我正在为Node.js node-oracledb使用Oracle数据库驱动程序。我做了一些研究,但没有找到关于如何对DB连接进行单元测试的明确解决方案。我应该连接到真实数据库还是模拟连接。哪个框架适合模拟数据库连接?我想单独测试post post request / API / login,这取决于oracledb。分享下面的代码。请指导。

var express = require('express');
var router = express.Router();
var oracledb = require('oracledb');
var jwt = require('jsonwebtoken');
var database = {};

router.use('/', function postLogins(req, res) {

  database.user = req.body.email.toUpperCase();
  database.password = req.body.password;
  database.connectString = process.env.DB_HOST;

  oracledb.getConnection(
    database,
    function connectToDatabase(connectionError, connection) {
      var payload;

      if (connectionError) {
        res.set('Content-Type', 'application/json');
        res.status(500).send(JSON.stringify({
          status: 500,
          message: 'Error connecting to DB',
          detailed_message: connectionError.message
        }));
        return;
      }

      payload = {
        sub: req.body.email
      };

      res.status(200).json({
        user: req.body.email,
        token: jwt.sign(payload, process.env.SECRET_KEY, { expiresIn: '8h' })
      });

      connection.release(function onRelease(releaseError) {
        if (releaseError) {
          console.error(releaseError.message);
        } else {
          console.log('POST /logins : Connection released');
        }
      });
    }
  );
});

module.exports = router;

1 个答案:

答案 0 :(得分:1)

我应该连接到真实数据库还是模拟连接。

这实际上取决于测试的范围。 Oracle是一种您无法控制且必须与之交互的依赖项。只要此代码在某个时刻执行,它就会被客户端测试,但希望在它到达客户端之前。我认为这两种方法都很有价值。

哪个框架适合模拟数据库连接?

我会尝试使用某种设计模式来隔离您的依赖项并提高可测试性。高度嵌套的匿名函数使得难以隔离代码的一部分,几乎要求您在粗略的级别上运行处理程序。有几个选项可以帮助拆分处理程序并使其在单元级别更易测试。我认为第一步可能是提取你的处理程序:

class PostLogins {
   constructor(db) {
     this.db = db || oracledb;
   }

   handle(req, res) {
     // use this.db
   }
}

var pl = new PostLogins();
router.use('/', pl.handle);

这将允许您直接运用您的处理程序,但当然不会测试它是否连接到您的框架。它还允许您为单元测试提供oracle的存根实现,以验证处理程序的流程是否正常工作。即使使用存根oracle进行单元测试,您也会忽略实际的oracle交互和http交互的覆盖范围。另一个有助于提高可测试性的重构就是打破connectToDatabase

根据项目的成熟度,首先创建一个启动oracle的粗粒度高级别测试,启动您的Web服务器然后运行您的端点并验证是否已收到成功响应可能是有意义的。我会选择这种方法,如果它在项目生命周期的早期阶段,并且实现仍在改变或者如果您的项目已经发布到客户端,允许您更改实现和重构,并且仍然具有HTTP和成功请求的测试覆盖率没有退步。