单元测试javascript / node中的嵌套对象

时间:2015-05-21 01:58:29

标签: javascript node.js unit-testing oop elasticsearch

我有一个名为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

访问elasticsearch客户端

第一个问题,这是一个合适的模式吗?如果没有,最好的是什么?

第二个问题(以及驱使我来到这里的那个),我如何模拟对this.client.index({})这样的事情的调用我只是开始在node / js下进行单元测试和模拟,所以我不这样做在框架方面确实有偏好(目前使用mocha / chai / sinon)

如果您想更详细地了解,则完整代码为here

2 个答案:

答案 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

相关问题