如何模拟ElasticSearch客户端特定方法

wbgh16ku  于 2023-01-01  发布在  ElasticSearch
关注(0)|答案(1)|浏览(150)

我有一段代码,我在其中调用了ElasticSearch指数统计。尝试模仿它以下的方式,但没有工作。

esIndicesStatsStub = sinon.stub(Client.indices.prototype, 'stats').returns({
        promise: () => new Error()
      })

我得到的错误是TypeError: Cannot read property 'prototype' of undefined
我有这样的源代码

const { Client } = require('@elastic/elasticsearch')
const esClient = new Client({
node:'some https url'
})
 esClient.indices.stats(params, function (err, data) {
                if (err) {
                    reject(err);
                } else {
                    if (data) {
    //do something 
                    } 
    //do some other thing
                }
    });

我如何用sinon正确模拟elasticsearch?因为我不被允许使用@elastic/elasticsearch-mock

wwtsj6pe

wwtsj6pe1#

由于ES SDK通过getter函数定义了一些API,如indices

Object.defineProperties(API.prototype, {
  //...
  indices: {
    get () { return this[kIndices] === null ? (this[kIndices] = new IndicesApi(this.transport)) : this[kIndices] }
  },
  //...
})

参见v8.5.0/源代码/应用程序接口/索引。ts#L372
我们应该使用stub.get(getterFn) API来替换这个存根的新getter。
对于直接分配给API.prototype.bulk.clearScroll等API,您可以调用sinon.stub(Client.prototype, 'bulk')来存根它们。
最后,由于您的代码是在模块作用域中定义的,所以当您import/require它时,代码将被执行。我们应该首先安排我们的存根,然后import/require模块。正如您所看到的,我使用动态import()
例如
index.ts

import { Client } from '@elastic/elasticsearch';
const esClient = new Client({ node: 'http://localhost:9200' });
esClient.indices.stats({ index: 'a' }).then(console.log);

index.test.ts

import sinon from 'sinon';
import { Client } from '@elastic/elasticsearch';
import { IndicesStatsResponse } from '@elastic/elasticsearch/lib/api/types';

describe('74949441', () => {
  it('should pass', async () => {
    const indicesStatsResponseStub: IndicesStatsResponse = {
      _shards: {
        failed: 0,
        successful: 1,
        total: 2,
      },
      _all: {
        uuid: '1',
      },
    };
    const indicesApiStub = {
      stats: sinon.stub().resolves(indicesStatsResponseStub),
    };
    sinon.stub(Client.prototype, 'indices').get(() => indicesApiStub);
    await import('./');
    sinon.assert.calledWithExactly(indicesApiStub.stats, { index: 'a' });
  });
});

试验结果:

74949441
{
  _shards: { failed: 0, successful: 1, total: 2 },
  _all: { uuid: '1' }
}
    ✓ should pass (609ms)

  1 passing (614ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

软件包版本:

"@elastic/elasticsearch": "^8.5.0",
"sinon": "^8.1.1",
"mocha": "^8.2.1",

相关问题