如何解决Node.js BigQuery 单元测试
我是编写 mocha 单元测试的新手,想问一下以下代码的单元测试会是什么样子(尤其是 BigQuery 部分)。代码位于 PubSub 触发的 Cloud Function 中,并将行插入 BigQuery 表中:
/**
* Triggered from a message on a Cloud Pub/Sub topic.
*
* @param {!Object} event Event payload.
* @param {!Object} context Metadata for the event.
*/
const {BigQuery} = require('@google-cloud/bigquery');
const bigqueryClient = new BigQuery();
const dataset = 'dataset_name';
const table = 'table_name';
exports.sendtobigquery = (event,context) => {
const pubsubMessage = Buffer.from(event.data,'base64').toString();
BigQueryInsert(pubsubMessage,dataset,table);
};
async function BigQueryInsert(pubsubMessage,table) {
const date = new Date().toISOString(); // new date
const rows = [{field1: pubsubMessage,field2: date}]; // new field2
await bigqueryClient
.dataset(dataset)
.table(table)
.insert(rows);
}
我在这里看到 Mocking ES6 BigQuery class 应该使用 sinon 和 proxyquire,但我不明白如何为我的代码准确地做到这一点。
感谢任何帮助。
更新:
我添加了一个新的日期字段作为行的一部分,但是在单元测试方面我也遇到了麻烦。对于我尝试在 sinon.usefaketimers
中使用 index.test.js
的日期,来自这样的答案
describe('66267929',() => {
const Now = new Date();
const date = sinon.usefaketimers(Now.getTime());
beforeEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it('should pass',async () => {
... // same code
... // same code
sinon.assert.calledWithExactly(bigqueryClientStub.insert,[{ field1: 'teresa teng',field2: date }]);
});
});
但这导致“AssertError:预期存根被调用一次但被调用了 0 次”。这怎么办?
解决方法
由于您在没有 BigQueryInsert
的情况下调用 async/await
函数,我们需要刷新 promise 队列以确保所有异步方法调用都已在 bigqueryClient
对象上完成。
我们使用 proxyquire 和 sinonjs 来存根 BigQuery
构造函数。
我们使用returnsThis()
来实现链式方法调用。
例如
index.js
:
const { BigQuery } = require('@google-cloud/bigquery');
const bigqueryClient = new BigQuery();
const dataset = 'dataset_name';
const table = 'table_name';
exports.sendtobigquery = (event,context) => {
const pubsubMessage = Buffer.from(event.data,'base64').toString();
BigQueryInsert(pubsubMessage,dataset,table);
};
async function BigQueryInsert(pubsubMessage,table) {
const rows = [{ field1: pubsubMessage }];
await bigqueryClient.dataset(dataset).table(table).insert(rows);
}
index.test.js
:
const proxyquire = require('proxyquire');
const sinon = require('sinon');
const flushPromises = () => new Promise((resolve) => setImmediate(resolve));
describe('66267929',() => {
afterEach(() => {
sinon.restore();
});
it('should pass',async () => {
const bigqueryClientStub = {
dataset: sinon.stub().returnsThis(),table: sinon.stub().returnsThis(),insert: sinon.stub().resolves(),};
const googleCloundBigqueryStub = {
BigQuery: sinon.stub().returns(bigqueryClientStub),};
const { sendtobigquery } = proxyquire('./',{
'@google-cloud/bigquery': googleCloundBigqueryStub,});
const data = Buffer.from('teresa teng').toString('base64');
sendtobigquery({ data });
await flushPromises();
sinon.assert.calledOnce(googleCloundBigqueryStub.BigQuery);
sinon.assert.calledWithExactly(bigqueryClientStub.dataset,'dataset_name');
sinon.assert.calledWithExactly(bigqueryClientStub.table,'table_name');
sinon.assert.calledWithExactly(bigqueryClientStub.insert,[{ field1: 'teresa teng' }]);
});
});
单元测试结果:
66267929
✓ should pass (343ms)
1 passing (346ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。