【问题标题】:unit testing nested objects in javascript/node在 javascript/node 中对嵌套对象进行单元测试
【发布时间】:2015-05-21 01:58:28
【问题描述】:

我有一个名为 NetFlowStorage 的对象,其中包含访问特定弹性搜索索引的方法。我的构造函数看起来像:

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

【问题讨论】:

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


【解决方案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,就像您在测试本身中注入模拟的 elasticsearch 客户端一样。

【讨论】:

  • 这是这类事物的首选模式吗?
  • 我会说这是解决它的好方法。然后,您可以将所有这些抽象到另一个层次,并拥有一个 EsNetFlowStorage 类,该类扩展了一个带有 elasticsearch 客户端的基本 NetFlowStorage 类和一个 RedisNetFlowStorage 类(如果您想要一个 redis 客户端)。你只需要注入一个不同的客户端
【解决方案2】:

我认为您应该将配置对象和连接对象传递给该方法。 因此,例如,如果您使用 Jasmine 进行测试,您可以传递一个 spy

 var client = {index:function(){}}
 spyOn(client, 'index');
....
expect(client.index)toHaveBeenCalled();

并在某个时候通过注入或单例将其传递给 SUT

【讨论】:

    猜你喜欢
    • 2021-08-02
    • 2017-07-01
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多