node.js - Firebase/Google Cloud Functions に依存関係を注入する方法は?(ユニットおよび統合テスト)
私の質問が本当に Firebase Cloud Functions に関連しているかどうかわかりませんが、Firebase Cloud Functions をテストしようとしてこの問題に出くわしました。
例えば、NodeJSで書かれたFirebase Cloud関数があるとしましょう:
function.ts
import * as functions from "firebase-functions"
const admin = require("firebase-admin")
import * as authVerifier from "../../auth/authVerifier"
export default functions.https.onRequest(async (req, res) => {
let authId
try {
authId = await authVerifier.identifyClientRequest(req)
} catch (err) {
console.error(`Unauthorized request error: ${err}`)
return res.status(401).send({
error: "Unauthorized request"
})
}
}
通常、私はインターフェースを持っており、テストしたい任意のクラスを簡単にモックできます。
そして、例えば、authVerifier は次のようになります:
authVerifier.ts
import * as express from "express"
export async function identifyClientRequest(req: express.Request) {
return true // whatever, it doesn't really matter, should be real logic here
}
私は function.ts をテストしようとしていて、res と req だけを渡すことができます。例えば:
function.test.ts
it("should verify client identity", async () => {
const req = {
method: "PUT"
}
const res = { }
await myFunctions(req as express.Request, res as express.Response)
// assert that authVerifier.identifyClientRequest(req) called with passed req
})
質問は次の通りです:function.ts と function.test.ts で異なる実装を使用するために、authVerifier.identifyClientRequest(req) をどのようにモックできますか?
私はあまり NodeJS/TypeScript を知らないので、テスト用に authVerifier の別のモッククラスをインポートできるかどうか疑問です。
回答 #1
わかった、答えを見つけたようです。念のためここに投稿しておきます。
SinonJS と Chai を使って、クラス(この場合は authVerifier)をスタブして必要な結果を返すことができます:
const chai = require("chai")
const assert = chai.assert
const sinon = require("sinon")
import * as authVerifier from "../../../src/auth/authVerifier"
it("should verify client identity", async () => {
const req = {
method: "PUT"
}
const res = mocks.createMockResponse()
const identifyClientRequestStub = sinon.stub(authVerifier, "identifyClientRequest");
const authVerifierStub = identifyClientRequestStub.resolves("UID")
await updateUser(req as express.Request, res as express.Response)
assert.isTrue(authVerifierStub.calledWith(req))
})
そして結果は:
