我有一个名为NetFlowStorage的对象,其中包含访问特定elasticsearch索引的方法。我的构造函数看起来像:
function NetFlowStorage() {
this.host = 'localhost:9200';
this.shards = '4';
this.replicas = '0';
this.index_name = 'flow_track2';
this.client = null;
}
在对象内部,我有一个名为connect的方法,当调用它时,它将建立连接并将elasticsearch客户端对象存储在this.client
属性中(如果还没有那个)。这样,所有对象方法都可以使用this.client
第一个问题,这是一个合适的模式吗?如果没有,最好的是什么?
第二个问题(以及驱使我来到这里的那个),我如何模拟对this.client.index({})
这样的事情的调用我只是开始在node / js下进行单元测试和模拟,所以我不这样做在框架方面确实有偏好(目前使用mocha / chai / sinon)
如果您想更详细地了解,则完整代码为here。
答案 0 :(得分:1)
对于类似的内容,我会使用dependency injection。
您想要将NetFlowStorage
类与实际的elasticsearch客户端分离:
function NetFlowStorage(esClient) {
this.host = 'localhost:9200';
this.shards = '4';
this.replicas = '0';
this.index_name = 'flow_track2';
// if you don't wanna share connections across several instances
// you can instantiate the client here otherwise you can pass the
// client instance
this.client = esClient; // or new esClient({ host: this.host })
}
这样您甚至不需要 elasticsearch 作为节点模块的一部分,甚至可以跨多个实例共享连接(或不共享?)
这种解耦还可以更容易模拟esClient
,就像在测试中注入模拟弹性搜索客户端一样。
答案 1 :(得分:1)
我认为您应该将配置对象和连接对象传递给该方法。 因此,如果您使用Jasmine进行测试,例如您可以通过间谍
var client = {index:function(){}}
spyOn(client, 'index');
....
expect(client.index)toHaveBeenCalled();
并在某个时刻通过注射或单个传递给SUT