gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 08:18:57 24 4
gpt4 key购买 nike

我是 Node.js 的新手,我正在为 HBase 编写 DAO 层,它将包装 thrift 并为其他层提供清晰的接口(interface)。我正在尝试使用 sinon.jsmocha 为其编写单元测试,但不确定如何确保模拟 Thrift 连接类及其事件处理程序的一个事件。

我的DAO代码如下:

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.');
});
}

对于上面的代码,我只想创建我管理的 stub primaryClusterConnectionclient 对象,但问题是 primaryClusterConnection 的 stub 没有'不知道 connect 事件及其处理程序,因此 console.log('Connected to HBase thrift server at '... line 永远不会被执行。我想测试一下代码的一部分。任何人都可以帮我为这个问题编写正确的 stub /模拟吗?

我的测试代码如下:

var hbaseDao = require('../../../src/dao/hbase/HBaseDao.js');
var libDirRelativePath = "../../../lib";
var hbaseThriftDirPath = libDirRelativePath + "/hbase-gen-nodejs";
var hbase = require(hbaseThriftDirPath + '/THBaseService');

var chai = require('chai');
var should = chai.should();
var expect = chai.expect;
var sinon = require('sinon');

describe("HBaseDao", function() {
describe(".putRows()", function() {

it("Should execute callback after inserting objects in HBase.", function(done) {
var commonStub = sinon.stub();
var connection = {
close : function() {
console.log('connection closed.');
}
};
commonStub.withArgs('nn2', 9090).returns(connection);
var client = {};
commonStub.withArgs(hbase, connection).returns(client);
var tableName = 'DUMMY_READINGS_TABLE';
var callBackMethod = function() {
console.log('dummy callback function.');
};
commonStub.withArgs(tableName, [], callBackMethod).returns(0);

hbaseDao.putRows(tableName, [], callBackMethod);
expect(hbaseDaoSpy.callCount).to.equal(1);
done();
});

最佳答案

让我们首先稍微简化一下问题。

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',并且断言它被调用一次,这是确保测试正常工作的另一种方法。现在考虑这个例子并将其应用于您原来的问题。

我想你几乎明白了,但是你需要将完成的回调放在回调 stub 中,如下所示:

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

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

话虽这么说,您应该保持 PrimaryClusterConnection 不变,并且在测试中不考虑 hbaseDao 的实现细节。

您提到:

primaryClusterConnection doesn't have any idea about connect

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

所以我认为最后,你错过了测试的重点,这只是应该执行回调...并且你删除了你甚至不需要的东西到。

尝试这样的事情:

//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);

});

关于javascript - 如何使用 sinon.js 模拟事件处理程序方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33805581/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com