這個firebase單元測試正在踢我的屁股。Firebase的單元測試雲功能:用sinon.js測試/模擬「交易」的「正確方法」是什麼
我已經通過the documentation並閱讀了他們提供的示例,並且已經獲得了一些經過測試的更基本的Firebase功能單元,但是我不知道如何驗證如何驗證transactionUpdated
傳遞給參考號.transaction
的函數正在更新current
對象。
我的努力可能是最好的說明,他們的child-count
sample code和我在編寫單元測試時做的很差。
比方說,我的功能,我想單元測試包括以下內容(直接從上面的鏈接所):
// count.js
exports.countlikechange = functions.database.ref('/posts/{postid}/likes/{likeid}').onWrite(event => {
const collectionRef = event.data.ref.parent;
const countRef = collectionRef.parent.child('likes_count');
// ANNOTATION: I want to verify the `current` value is incremented
return countRef.transaction(current => {
if (event.data.exists() && !event.data.previous.exists()) {
return (current || 0) + 1;
}
else if (!event.data.exists() && event.data.previous.exists()) {
return (current || 0) - 1;
}
}).then(() => {
console.log('Counter updated.');
});
});
單元測試代碼:
const chai = require('chai');
const chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
const assert = chai.assert;
const sinon = require('sinon');
describe('Cloud Functions',() => {
let myFunctions, functions;
before(() => {
functions = require('firebase-functions');
myFunctions = require('../count.js');
});
describe('countlikechange',() => {
it('should increase /posts/{postid}/likes/likes_count',() => {
const event = {
// DeltaSnapshot(app: firebase.app.App, adminApp: firebase.app.App, data: any, delta: any, path?: string);
data: new functions.database.DeltaSnapshot(null, null, null, true)
}
const startingValue = 11
const expectedValue = 12
// Below code is misunderstood piece. How do I pass along `startingValue` to the callback param of transaction
// in the `countlikechange` function, and spy on the return value to assert that it is equal to `expectedValue`?
// `yield` is almost definitely not the right thing to do, but I'm not quite sure where to go.
// How can I go about "spying" on the result of a stub,
// since the stub replaces the original function?
// I suspect that `sinon.spy()` has something to do with the answer, but when I try to pass along `sinon.spy()` as the yields arg, i get errors and the `spy.firstCall` is always null.
const transactionStub = sinon.stub().yields(startingValue).returns(Promise.resolve(true))
const childStub = sinon.stub().withArgs('likes_count').returns({
transaction: transactionStub
})
const refStub = sinon.stub().returns({ parent: { child: childStub }})
Object.defineProperty(event.data, 'ref', { get: refStub })
assert.eventually.equals(myFunctions.countlikechange(event), true)
})
})
})
我註釋上面的源代碼與我的問題,但我會在這裏重申。
我如何可以驗證該transactionUpdate
callback,傳遞給交易存根,將我的startingValue
,它發生變異,expectedValue
,然後讓我觀察到的變化,並斷言,它發生了。
這可能是一個非常簡單的問題,但有一個明顯的解決方案,但我對測試JS代碼非常新,因爲它的一切都需要被截斷,所以它有點像學習曲線......任何幫助都會被讚賞。
太棒了!感謝資源和迴應。除了測試之外,我對雲功能產品印象深刻,功能非常強大 - 文檔通常也很好,僅缺少測試部門。對你和你的團隊來說很棒的工作。 – tim
謝謝蒂姆!如果您遇到更多問題,請告訴我們。我們渴望讓所有的事情都變得可怕。 :) –
@ Robert-JanHuijsman我也對Firebase留下了深刻的印象,我已經投入了最後3天,因爲我認爲這將成爲我和其他人的後端的未來。我希望你有一件事是路線圖。所以我們可以知道你在做什麼。 – Ced