首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在JavaScript中模拟pg?

如何在JavaScript中模拟pg?
EN

Stack Overflow用户
提问于 2015-07-02 18:47:07
回答 1查看 2.9K关注 0票数 4

我对mock的概念和javascript编程也是新手。我想在javascript程序中模拟pg (postgres模块)。我可以模仿非常简单的场景,但实际上我不能。

这是我的userHandler.js:

代码语言:javascript
复制
var pg = require('pg');
var connectionString = process.env.DATABASE_URL || 'postgres://admin:admin@localhost:5432/mydb';

exports.handlePost = function(req,res){

  var results = [];

  // Grab data from http request
    var adata = [req.body.Username, ..., req.body.FaxNum];  //Ignore for short.

  // Get a Postgres client from the connection pool
  pg.connect(connectionString, function(err, client, done) {

        // SQL Query > Insert Data
        var func_ = 'SELECT Dugong.Users_Add($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19)';
        var addUser_ = client.query(func_, adata);

        addUser_.on('error', function(error){
            var data = {success : false, 
                        username : req.body.Username,
                        reason : {errmsg : error.detail,
                                    errid : 'addUser_' }};
            return res.json(data);
        });

        addUser_.on('end',function(result){
            var data = {success : true, username : req.body.Username};
            console.log('Insert record completed');
            return res.json(data);
        });

    // Handle Errors
    if(err) {
      console.log(err);
      return ;
    }
    return;
  });
};

这是我的单元测试文件。m_users_page.js:

代码语言:javascript
复制
var express = require('express');
var router = express.Router();
var test = require('unit.js');
var mock = require('mock');
var httpMocks = require('node-mocks-http');
var real_users_page = require('../routes/users_page.js');

var b = mock("../routes/userHandler.js", {
    pg: {
        connect: function (connectionString,callback) {
                    if(connectionString === 'postgres://admin:admin@localhost:5432/skorplusdb'){
                        console.log('333');

                        //pseudo object
                        var client = {query : function(func_, adata, cb){
                            cb(null,adata);
                        }};

                        client.on('error', 'test emit the error in my mock unit.');

                        //pseudo done object
                        var done = function(){};
                        callback(null, client, done);

                        return ;
                    }
      }
  }
}, require);

describe('Test with static login', function(){

    it('Test simple login', function(done){
        var request  = httpMocks.createRequest({
        method: 'POST',
        url: '/users',
        body: { Username:"Je", ..., FaxAreaCode:'232'} //Ignore for short
    });

    var response = httpMocks.createResponse();

        b.handlePost(request,response, function(){
            var data = response._getData();
            console.log("7777777777" + data);

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

下面是错误:

代码语言:javascript
复制
$ mocha testing/m_users_page.js


  Test with static login
333
    1) Test simple login


  0 passing (7ms)
  1 failing

  1) Test with static login Test simple login:
     TypeError: Object #<Object> has no method 'on'
      at Object.mock.pg.connect (testing/m_users_page.js:22:14)
      at Object.exports.handlePost (routes/userHandler.js:30:6)
      at Context.<anonymous> (testing/m_users_page.js:63:5)

我的问题是:

在Node + Express + Mock + node-mocks-http?

  • How中做单元测试的合适方式是什么?要找到好的框架和好的文档,我必须阅读
  1. 。几天后,我开始在搜索引擎的搜索结果中打转。它们太简单了,我不能使它适应我的问题。
EN

回答 1

Stack Overflow用户

发布于 2018-08-25 07:34:00

首先,确保您理解单元测试和集成测试之间的区别。如果您想对实际的数据库进行测试,即使它有一个虚拟数据集,这也是一个集成测试,它不需要模拟:只需连接到具有虚拟数据的数据库即可。

但是假设你想测试你的the服务器模块,并且你想模拟db。首先,将数据库模块作为参数传递,而不是直接请求pg。另外,使用您自己的类包装postgres接口:

代码语言:javascript
复制
const { Pool } = require('pg');

module.exports = class DatabaseInterop {
  // Connection parameters can be passed to the constructor or the connect method, parameters to
  // DatabaseInterop::connect will override the initial constructor parameters.
  constructor ({
    user,
    password,
    database,
    host,
    logger={log: console.log, err: console.error},
  }) {
    this.logger = logger;
    this._params = {
      user,
      password,
      database,
      host,
    };
  }

  connect (params) {
    const {
      user,
      password,
      database,
      host,
    } = Object.assign({}, this._params, params);

    this._pool = new Pool({
      user,
      password,
      database,
      host,
    });

    ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
        'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'
    ].forEach(function (sig) {
        process.on(sig, async () => {

          logger.log(`Exiting for ${sig}...`);
          process.exit(0);
        });
    });

    return this;
  }

  async stop () {
    return this._pool.end();
  }

  runQuery (queryString, params=[]) {
    return params.length ? this._pool.query(queryString, params) : this._pool.query(queryString);
  }
};

现在,为了模拟它,您可以简单地在测试文件中扩展您的自定义类:

代码语言:javascript
复制
const DatabaseInterop = require('/path/to/database_interop.js');
class MockDB extends DatabaseInterop {

    connect () {
      // no-op
    }

    runQuery (qs, ...params) {
      // return whatever
    }

    stop () {
      // noop
    }
}

现在,对于您的测试,您可以注入mock,而您的实际系统将注入实际的接口。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31182449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档