Reputation: 153
I would like to write some unit tests for a bunch of cloud functions. Now I'm facing the following issue. Using the firebase-functions-test
I'm somehow not able to test HTTP triggered cloud functions. Here are some of my cloud functions that i'd like to test using jest
:
export cloudFunctions = {
createUserByAdmin: functions.runWith({ timeoutSeconds: 30, memory: '256MB' }).https.onCall(UserService.createUserByAdmin),
updateUserByAdmin: functions.runWith({ timeoutSeconds: 30, memory: '256MB' }).https.onCall(UserService.updateUserByAdmin),
deleteUserByAdmin: functions.runWith({ timeoutSeconds: 30, memory: '256MB' }).https.onCall(UserService.deleteUserByAdmin)
}
They are all deployed on Firebase and they work without problems. But I couldn't find a way to call the using the firebase-functions-test
package. Also, there are a few examples of how to write unit tests using that package but none of them test http triggered functions.
This is my test file:
import * as functions from 'firebase-functions-test'
import * as admin from 'firebase-admin'
import * as path from 'path'
const projectConfig = {
projectId: 'test-fb',
}
const testEnv = functions(
projectConfig,
path.resolve('DO-NOT-EDIT.dev.fb-admin-sdk-key.json'),
)
describe('[Cloud Functions] User Service', () => {
let cloudFunctions
beforeAll(() => {
cloudFunctions = require('../index')
})
afterAll(() => {
// delete made accounts/entrys
})
describe('Testing "createUserByAdmin"', () => {
it('Creating User does work', () => {
expect(1).toBe(0)
})
})
})
Does someone know how to test http cloud functions? I would really appreciate an example. Thanks!
Upvotes: 6
Views: 2442
Reputation: 153
I actually found a way on how to test HTTP Cloud Functions using firebase-functions-test
it all works with a wrapper function. Take a look at this reference page. Here is some code to make things a bit more clear.
this is a snippet from one of my tests
import * as functions from 'firebase-functions-test'
import * as admin from 'firebase-admin'
import * as path from 'path'
const projectConfig = {
projectId: 'myproject-id',
}
const testEnv = functions(
projectConfig,
path.resolve('fb-admin-sdk-key.json'),
)
// has to be after initializing functions
import * as cloudFunctions from '../index'
describe('Testing "createUserByAdmin"', () => {
const createUserByAdmin = testEnv.wrap(cloudFunctions.createUserByAdmin)
it('Creating User does work', async (done) => {
const data = {
displayName: 'Jest Unit Test',
email: '[email protected]',
password: 'password',
uid: null,
}
const context = {
auth: {
token: {
access: 'somestring,
},
uid: 'mockuiddddd',
},
}
await createUserByAdmin(data, context)
.then(async (createdUser: any) => {
expect(createdUser.status).toBe('OK')
done()
})
.catch((error: any) => {
fail('createUserByAdmin failed with the following ' + error)
})
})
})
You'll see that after initializing our test environment using our projectConfig
and our service account key file.
const testEnv = functions(
projectConfig,
path.resolve('fb-admin-sdk-key.json'),
)
you'll just have to wrap the appropriate cloud function with the .wrap()
function.
const createUserByAdmin = testEnv.wrap(cloudFunctions.createUserByAdmin)
And you can call it like every other function (keep in mind that cloud functions usually expect a data parameter (with the variables you use in your cloud function) as well as a context parameter, depending on how you handle authentication/authorization you'll have to try and error to find the right context properties your function requests.
if your writing tests for your production cloud functions make sure to clean up after running tests - such as deleting created accounts or deleting data in either firestore or realtime-database
Upvotes: 7