2017-05-04 101 views
0

我正在使用mocha,nodejs和pg-promise连接到Postgres数据库。我想知道如何单元测试执行DML的函数?这只是一个简单的例子:单元测试函数连接到Postgres数据库

export function insertUser(db, { firstName, lastName }) { 
    db.one(` 
    INSERT INTO users 
    (
     firstName, 
     lastName 
    ) 
    VALUES 
    (
     $<firstName>, 
     $<lastName> 
    ) 
    `, { firstName, lastName }); 
} 

如果在查询中有拼写错误,单元测试如何捕获它?我可以创建一个测试数据库,即时创建临时表,但这会导致我的测试速度变慢。

+0

使用示例:https://coderwall.com/p/axugwa/cleaning-the-database-in-between-mocha-tests-with-pg-promise –

+0

@ vitaly -t - 我可以看到几个与此相关的问题做法。首先,它会减慢单元测试,因为它会连接到数据库。其次,维护起来会比较困难,因为我们需要创建一个新的测试数据库,它是主数据库的完全复制品。第三,它就像我们正在测试pg-promise功能。在单元测试中,我们假设pg-promise是自己正确测试的,所以不需要测试它的功能。 – Chris

+0

对数据库代码的现代测试需要良好的隔离性,这意味着要使用Travis CI这样的系统,这为您的每个PR-s提供了一个全新的数据库,这是一条可行的路线。如果你在本地运行测试,它们不会很慢,它们速度非常快,我一直都在这样做。此外,不知道你是什么意思,这就像测试pg-promise功能一样。 –

回答

1

鉴于db变量是一个函数参数,单元测试这种类型的代码将是直截了当的。

继续并安装模拟库。我们与sinonjs取得了很好的成功。

npm install sinon --save-dev 

与模拟库的地方,你现在可以如下创建单元测试,沿着线的东西:

const should = require('should'), 
     sinon = require('sinon'), 
     helper = require('your-db-module'); 

describe('DB functions',() => { 
    describe('insertUser',() => { 
    const { insertUser } = helper; 

    it('correctly inserts a new user',() => { 
     const db = { 
     one: sinon.stub() 
     }; 

     insertUser(db, { firstName: 'john', lastName: 'doe' }); 

     db.one.calledWithExactly('INSERT INTO users(firstName, lastName) VALUES($<firstName>, $<lastName>)', { firstName: 'john', lastName: 'doe'}).should.eql(true); 
    }); 
    }); 
}); 

这应该使你动身的右脚上。

+0

所以我们需要将代码中的查询复制到测试中。我只是想着用这种方法,开发人员只需将测试中的查询复制并粘贴到代码中即可。如果我将“INSERT”拼写为“INSET”会怎么样?单元测试如何捕获错误? – Chris

+0

恕我直言,你应该在编写函数本身之前编写测试以帮助避免这种情况。除此之外,您还可以在此代码区域进行一次或多次函数测试,以检查事情是否按预期工作。这应该超过足够的测试覆盖率来继续。 –