如何使用sinon.js模拟事件处理程序方法?

时间:2015-11-19 13:41:02

标签: javascript node.js unit-testing mocha sinon

我是ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "text", "jsmethod();", true); 的新手,我正在为HBase编写DAO图层,它将包装thrift并为其他图层提供清晰的界面。我正在尝试使用Node.jssinon.js为它编写单元测试,但不确定如何确保模拟Thrift连接类及其事件处理程序的一个事件。

我的DAO代码如下:

mocha

对于上面的代码我只想创建我已经管理的存根var thrift = require('thrift'); var libDirRelativePath = "../../../lib"; var hbaseThriftDirPath = libDirRelativePath + "/hbase-gen-nodejs"; var hbase = require(hbaseThriftDirPath + '/THBaseService'); var hbaseTypes = require(hbaseThriftDirPath + '/hbase_types'); var thritfPrimaryServerAddress = 'nn2'; var thritfBackupServerAddress = 'backup-nn2'; var thriftServerPort = 9090; exports.putRows = function(tableName, putObjectArray, callback) { var primaryClusterConnection = thrift.createConnection(thritfPrimaryServerAddress, thriftServerPort, { transport: thrift.TBufferedTransport, protocol : thrift.TBinaryProtocol }); console.log('DEBUG : connection object created.'); var client = thrift.createClient(hbase, primaryClusterConnection); console.log('DEBUG : client object created.'); primaryClusterConnection.on('connect', onConnectOfPutRows); primaryClusterConnection.on('connect', function() { console.log('Connected to HBase thrift server at ' + thritfPrimaryServerAddress + ":" + thriftServerPort); client.putMultiple(tableName, putObjectArray, callback); connection.close(); }); primaryClusterConnection.on('error', function() { console.log('Error occurred in HBase thirft server connection.'); }); } primaryClusterConnection对象,但问题是client的存根对{{{}}没有任何想法1}}事件及其处理程序,因此primaryClusterConnection行永远不会被执行。我也想测试那部分代码。任何人都可以帮我写这个问题的正确存根/模拟吗?

我的测试代码如下:

connect

1 个答案:

答案 0 :(得分:1)

让我们先简化一下这个问题。

it.only("Should execute callback after inserting objects in HBase.", function(done) {

    var events = require('events');
    var hbaseDao = new events.EventEmitter();
        hbaseDao.putRows = function() {
            console.log('putting rows');
            this.emit('notify');
        };
        hbaseDao.on('notify', function(){
            console.log('notify event fired');
            done(); //here's where you call the callback to assert that the event has fired
        });

    sinon.spy(hbaseDao, 'putRows');

    var commonStub = sinon.stub();
    var tableName = 'DUMMY_READINGS_TABLE';
    var client = {};
    var connection = {
        close : function() {
            console.log('connection closed.');
        }
    };
    var callBackMethod = function() {
        console.log('dummy callback function.');
    };

    commonStub.withArgs('nn2', 9090).returns(connection);
    commonStub.withArgs({}, connection).returns(client);
    commonStub.withArgs(tableName, [], callBackMethod).returns(0);

    hbaseDao.putRows(tableName, [], callBackMethod);

    //assertions
    assert(hbaseDao.putRows.calledOnce);

});

上述测试将起作用,因为它会创建一个新的" hbaseDao"从一个简单的事件发射器,并准备好方法和通知事件。

因为我们正在进行异步测试,所以我们需要在规范中进行完成回调。请注意,这只会触发"完成"当事件发生时。因此,除非事件触发,否则测试不会通过。另请注意,我们专门针对hbaseDao' putRows'并且我们声称它被称为一次,这是确保测试正常工作的另一种方式。现在考虑这个例子并将其应用于您的原始问题。

我认为你几乎得到了它,但是你需要在回调存根中完成回调:

var callBackMethod = function() {
    console.log('dummy callback function.');
    done();
 };

这样,当你的primaryClusterConnection.on('connect')事件被触发时,提供的回调将执行完成并完成测试。

话虽如此,您应该保持您的primaryClusterConnection完好无损,并且在您的测试中不要考虑hbaseDao的实现细节。

你提到过:

  

primaryClusterConnection对连接

一无所知

但这可能是正确的,因为您在测试中创建了一个新连接,并且您的实现中没有任何内容告诉我您已更改了连接的事件处理程序。 / p>

所以我认为最后,你错过了测试的重点,这只是should execute callback...而且你正在剔除你甚至不需要的东西。

尝试这样的事情:

//use it.only to make sure there's no other tests running
it.only("Should execute callback after inserting objects in HBase.", function(done) {

    //get the class
    var hbaseDao = require('../../../src/dao/hbase/HBaseDao.js');

    //spy on the method
    sinon.spy(hbaseDao, 'putRows');

    //create a table name
    var tableName = 'DUMMY_READINGS_TABLE';

    //create callback method with done.
    var callBackMethod = function() {
        console.log('dummy callback function.');
        done();
    };

    //run the function under test
    hbaseDao.putRows(tableName, [], callBackMethod);

    //assert called once
    assert(hbaseDao.putRows.calledOnce);

});