简体   繁体   English

使用带有nodeunit的DB连接/驱动程序编写单元测试

[英]Writing unit tests with DB connections/drivers with nodeunit

I am trying to write a set of test units for my simple DB layer SimpleDbLayer using nodeunit . 我正在尝试使用nodeunit为我的简单数据库层SimpleDbLayer编写一组测试单元。 I am finding it rather difficult. 我发现这很困难。

Problems: 问题:

1) I want to connect to the DB once, and use that connection. 1)我想一次连接到数据库,并使用该连接。 I cannot really use setUp and tearDown, as they are run before and after each test. 我不能真正使用setUp和tearDown,因为它们分别在每次测试之前和之后运行。 As a "solution", I am using a module-wide variable for the scope (see code below) 作为“解决方案”,我在范围内使用模块范围的变量(请参见下面的代码)

2) My simple DB layer has several DB drivers. 2)我的简单数据库层有几个数据库驱动程序。 MongoMixin is only one of them -- I have under development MariaMixin and PostgresMixin. MongoMixin只是其中之一-我正在开发MariaMixin和PostgresMixin。 Ideally I would run these tests one for each driver, to see if they work. 理想情况下,我将为每个驱动程序运行一次这些测试,以查看它们是否有效。 Is there a good, easy way to do this? 有没有一种简便的好方法?

3) I am hitting cases where I make a mistake with the code of my test, and all I get is a complaint about test.done not being detected. 3)我遇到的情况是我的测试代码有误,而我得到的只是关于test.done的投诉。 Is there any trickery I need to be aware of here? 在这里我需要注意一些技巧吗?

4) Am I doing anything horribly wrong? 4)我做错什么了吗? (see code) (请参见代码)

var 
  dummy

, declare = require('simpledeclare')
, SimpleDbLayer = require('./SimpleDbLayer')

, MongoMixin = require('./MongoMixin.js')

, mw = require('mongowrapper')
, async = require('async')
;

var db, layer;


exports.createLayer = {

  databaseConnect: function( test ){
    mw.connect('mongodb://localhost/hotplate', {}, function( err, returnedDb ){
      test.ifError( err );
      db = returnedDb;
      test.done( null );
    });
  },


  makeLayer: function( test ){

    var C = declare( [ SimpleDbLayer, MongoMixin ] );
    layer = new C( 'test', {  name: true, surname: true, age: true }, db );

    test.ok( layer );
    test.done(); 
  },

  deleteAll: function( test ){
    layer.delete( { }, { multi: true }, function( err, howmany ){
      test.ifError( err );
      test.done();
    });
  },

  insert: function( test ){
    var people = [
      { name: 'Chiara',    surname: 'Mobily',     age: 24 },
      { name: 'Tony',      surname: 'Mobily',     age: 37 },
      { name: 'Sara',      surname: 'Connor',     age: 14 },
      { name: 'Daniela',   surname: 'Mobily',     age: 64 },
    ];

    returnedPeople = [];

    var functions = [];

    // Populate the database
    people.forEach( function( person ){

      functions.push( function( done ){
        layer.insert( person, { returnRecord: true }, function( err, person ){
          test.ifError( err );
          returnedPeople.push( person );
          done( null );
        })
      })

    })

    async.series( functions, function( err, res ){
      test.ifError( err );
      test.done();
    });

  },

  databaseDisconnect: function( test ){
    db.close();
    test.done();
  },

} 

Answering myself. 回答我自己。 The solution is simple: for each driver, this is the test.js file: 解决方案很简单:对于每个驱动程序,这是test.js文件:

var driver = require('./specificDriver'); var driver = require('./ specificDriver'); var simpledblayerTests = require( "./lib/simpledblayer/test.js" ); var simpledblayerTests = require(“ ./lib/simpledblayer/test.js”);

var tests = simpledblayerTests.get(

  function getDbInfo( done ) {
    mw.connect('mongodb://localhost/tests', {}, function( err, db ){
      if( err ){
        throw new Error("MongoDB connect: could not connect to database");
      } else {
        done( null, db, driver );
      }
    });
  },

  function closeDb( db, done ) {
    db.close( done );
  }
);


for(var test in tests) {
    exports[ test ] = tests[ test ];
}

Basically, the get() function exported by the actual "main" module (more about this later) takes two parameters: two functions that open and close the database connection. 基本上,由实际的“主”模块导出的get()函数(稍后会详细介绍)具有两个参数:两个用于打开和关闭数据库连接的函数。

That get() function returns a bunch of functions ready to be exported -- the functions that make up your unit testings. get()函数返回一堆准备好导出的函数-构成单元测试的函数。

The main module will have something like this: 主模块将具有以下内容:

exports.get = function( getDbInfo, closeDb ){

  var tests;
  var g = {};

  var startup = function( test ){
    var self = this;

    test.doesNotThrow( function(){

      getDbInfo( function( err, db, driver ){
        if( err ){
          throw( new Error("Could not connect to db, aborting all tests") );
          process.exit();
        }

        // Set the important g.driver variables (db and driver)
        g.db = db;
        d.driver = driver

        test.done();
      });
    });
  }


  var finish = function( test ){
    var self = this;
    closeDb( g.db, function( err ){
      if( err ){
        throw( new Error("There was a problem disconnecting to the DB") );
      }
      test.done();
    });
  };

  tests = {

    startup: startup,

    // ...
    // Your tests here. All functions will have access to g.db and g.driver 
    // ...

    finish: finish

  }

  return tests;
}

This way, every single module will run the same tests. 这样,每个模块都将运行相同的测试。 However, the driver variable and the functions to connect/disconnect to the database will be simple. 但是, driver变量和用于连接/断开数据库的功能将很简单。

See it in action with real code: 使用实际代码查看它:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 编写适当的单元测试 - Writing proper unit tests 编写表单元素的单元测试 - Writing Unit Tests for Form Elements 为vue-multiselect编写单元测试 - writing unit tests for vue-multiselect 为浏览器编写TSX(TypeScript for JSX / React)的单元测试 - Writing Unit Tests for TSX (TypeScript for JSX/React) for the Browser 为在JavaScript中使用jwt令牌的方法编写单元测试 - Writing unit tests for method that uses jwt token in javascript 在本地运行SLS函数以进行单元测试,结果是节点Mysql连接池“连接过多” - Running SLS Functions Locally for Unit Tests Results in Node Mysql Connection Pool 'Too Many Connections' 编写TypeScript单元测试时可以猴子补丁依赖性吗 - Can I monkey-patch dependencies when writing TypeScript unit tests 在编写服务器端Javascript的单元测试时如何处理外部模块 - How to handle external modules when writing unit tests for server-side Javascript 使用Mock.Interactions模拟鼠标覆盖聚合物元素的单元测试 - simulate mouse over writing unit tests for Polymer elements using Mock.Interactions 在为依赖于所述数据的函数编写单元测试时如何模拟数据? - How to mock data when writing unit tests for a function that relies on said data?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM