模拟 ES6 BigQuery class

Mocking ES6 BigQuery class

我有一个小的 class,它包装了一个基本的大查询操作:

const { BigQuery } = require('@google-cloud/bigquery');


export default class BQ {
    bigquery;

    constructor(projectId, keyFilename) {
        const options = {
            projectId,
            keyFilename,
            autoRetry: true,
        };
        
        this.bigquery = new BigQuery(options);
    }

    async query(query) {
        const options = {
            query,
            location: 'us',
        };
        const [job] = await this.bigquery.createQueryJob(options);
        const [rows] = await job.getQueryResults();
        return rows;
    }
}

我正在尝试为 query 方法编写 mocha 单元测试。但是,我一直坚持在 js 中创建模拟。 Sinon、沙盒、存根等有很多选项。我认为我需要存根实例属性,例如

const bq = new BQ(projectId, keyFilename);
const bqStub = sandbox.stub(bq, 'bigquery');

但是有些方法一直在尝试对 google 进行实际授权,我也需要对其进行存根。任何关于如何开始的帮助都会很棒。

您可以使用 Link Seams with CommonJS, we need proxyquire 构建我们的接缝。

例如

bq.js:

const { BigQuery } = require('@google-cloud/bigquery');

export default class BQ {
  bigquery;

  constructor(projectId, keyFilename) {
    const options = {
      projectId,
      keyFilename,
      autoRetry: true,
    };

    this.bigquery = new BigQuery(options);
  }

  async query(query) {
    const options = {
      query,
      location: 'us',
    };
    const [job] = await this.bigquery.createQueryJob(options);
    const [rows] = await job.getQueryResults();
    return rows;
  }
}

bq.test.js:

import proxyquire from 'proxyquire';
import sinon from 'sinon';

describe('62492844', () => {
  it('should pass', async () => {
    const rows = [{ id: 1 }, { id: 2 }];
    const job = {
      getQueryResults: sinon.stub().returns([rows]),
    };
    const bigquery = {
      createQueryJob: sinon.stub().returns([job]),
    };
    const BigQueryStub = sinon.stub().returns(bigquery);
    const BQ = proxyquire('./bq', {
      '@google-cloud/bigquery': { BigQuery: BigQueryStub },
    }).default;

    const bq = new BQ('projectId', './svc.json');
    sinon.assert.calledWithExactly(BigQueryStub, {
      projectId: 'projectId',
      keyFilename: './svc.json',
      autoRetry: true,
    });
    const actual = await bq.query('query');
    sinon.assert.calledWithExactly(bigquery.createQueryJob, { query: 'query', location: 'us' });
    sinon.assert.calledOnce(job.getQueryResults);
    sinon.assert.match(actual, rows);
  });
});

单元测试结果:

  62492844
    ✓ should pass (2427ms)


  1 passing (2s)

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