我正在围绕HttpsCallable云功能设计一个后端api(适用于android和iOS应用程序(。通过应用程序测试它们会变得非常麻烦,所以我希望切换到使用firebase-functions-test
工具对功能进行单元测试(在生产部署之前(。我一直在学习这个单元测试教程。
我在联机模式下运行单元测试时遇到了一些问题。让我提供一些细节。
这是我的"package.json"内容:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"test": "mocha --reporter spec"
},
"engines": {
"node": "8"
},
"dependencies": {
"@google-cloud/tasks": "^1.9.0",
"@googlemaps/google-maps-services-js": "^2.0.2",
"chai": "^4.2.0",
"firebase-admin": "^8.6.0",
"firebase-functions": "^3.3.0",
},
"devDependencies": {
"eslint": "^5.12.0",
"eslint-plugin-promise": "^4.0.1",
"firebase-functions-test": "^0.1.7",
"mocha": "^7.1.1"
},
"private": true
}
我从firebase后端使用谷歌API(方向、地理编码等(,因此,为了能够在运行测试时访问它们,我按照单元测试教程中的建议配置了位于test/index.test.js
的测试,如下所示:
const firebaseConfig = {
apiKey: ...,
authDomain: ...,
databaseURL: "https://my-project.firebaseio.com",
projectId: "my-project",
storageBucket: "my-project.appspot.com",
messagingSenderId: ********,
appId: *********
};
const test = require('firebase-functions-test')(firebaseConfig
, 'path_to_json_keyfile/myproject.json');
下面是示例测试代码。请注意,我所有的可调用函数都返回HttpsError,下面的测试只是检查HttpsError
的code
字段,如果它是ok
,则测试通过。我正在测试的函数位于一个单独的rides.js
文件中,index.js
将其导出为exports.rides = require(./rides.js)
(以下未显示(
const chai = require('chai');
const assert = chai.assert;
describe('Cloud functions', () => {
let rideFunctions;
before(() => {
rideFunctions = require('../index.js');
});
after(() => {
test.cleanup();
});
describe('getRideEstimate', () => {
it('should return ok', async () => {
data = {
riderType: 1,
pickup_lat: 37.0,
pickup_lng: -122,
dropoff_lat: 37.01,
dropoff_lng: -122.01,
scheduledTime: 1585939000,
ts: 1585939000,
tz_id: "uslax"
}
context = {
auth: {
uid: AUTH_ID_FOR_USER_ACCOUNT
}
};
const wrappedGetRideEstimate = test.wrap(rideFunctions.rides.getRideEstimate);
let httpsError = await wrappedGetRideEstimate(data, context);
return assert.equal(httpsError.code, 'ok');
});
})
describe('testCallable', () => {
it('should return ok', async () => {
data = {}
context = {}
const wrappedTestCallable = test.wrap(rideFunctions.rides.testCallable);
let httpsError = await wrappedTestCallable(data, context);
return assert.equal(httpsError.code, 'ok');
})
})
})
问题
- 我的形式的简单
testCallable
函数
exports.testCallable = functions.https.onCall((data, context) => {
console.log('testCallable');
return new functions.https.HttpsError('ok', '', '');
})
通过了测试(正如预期的那样(,但令人费解的是,它似乎是在离线模式下运行的,因为在Firebase控制台的云功能日志中没有记录。此外,如果我禁用笔记本电脑的连接,测试结果保持不变,这表明该功能在离线模式下运行。
My
getRideEstimate
函数调用googleDirections
API,返回一个长时间的400
错误,表明在形成对Directions API的请求时出现了一些问题。我不知道这个错误是否与第一个问题有关,但由于Directions API调用嵌入在getRideEstimate
函数的更深处,这确实表明函数正在被调用,但不知何故API调用失败了。有没有其他方法可以在联机模式下测试HttpsCallable函数?
对我来说,这很有效:
import * as firebaseSetup from 'firebase-functions-test';
export const testEnvironment = firebaseSetup({
databaseURL: "https://project-id.firebaseio.com",
projectId: 'project-id'
}, './service-account-project-id-firebase-adminsdk.json');
你可以在下面找到一个完整的YouTube教程:https://youtu.be/UDMDpdu5-rE?t=1122