如何快速测试Firebase功能

时间:2019-05-22 23:27:59

标签: typescript firebase google-cloud-functions

我在Firebase函数上使用Typescript。在开发过程中,我发现很难用代码进行测试(或试验)。我使用的是Lint插件,因此在租借时我看到必须运行代码而出现的错误。

但是我无法运行代码并查看输出:

我有以下代码要修正和测试:

    export const onPostUpdate = functions.database
.ref('/Posts/{uid}/{postID}')
.onCreate((snapshot, context) => {
  const uid = context.params.uid
  const postID = context.params.postID
  console.log('New postID:', postID)
  console.log('New uid:', uid)

  // const postData = snapshot.val()
  // console.log('New postData: ${postData["Media"]}')

  export const getUsersToBeUpdated = functions.https.onRequest((request, response) => {
    admin.database().doc('PeopleWhoFollowMe/\(uid)').get()
    .then(snapshot => {
      const data = snapshot.data()
      response.send(data)
    })
    .catch(error => {
      //handle error
      console.log(error)
      response.status(500).send(error)
    })
  })
  return console.log('New postID:', postID)
})

在这种情况下,我不知道它将输出什么:response.send(data)

那我有哪些更快的测试选项?

更新:

基于我的question here.,看来我无法模拟实时数据库触发器,因为它尚不支持。鉴于此,我有哪些快速测试选项?

1 个答案:

答案 0 :(得分:1)

我有一个具有后台功能(onUpdate,OnCreate)和HTTP功能的项目。 我发现进行测试的最简单方法是使用简单的单元测试。

测试应该成为编程生活的一部分。刚开始时会感到很麻烦,但可以节省很多时间,尤其是使用云功能

在您的代码中,似乎您编写了两个函数。一个是数据库触发器,另一个是HTTP函数。

我将尝试为每一个编写测试,以向您展示我将如何做。我使用jest

/functions
|--index.js
|--onCreate.js
|--getUsersToBeUpdated.js
|--/test
   |--onCreate.spec.js
   |--getUsersToBeUpdated.spec.js

index.js

const functions   = require('firebase-functions');

const onCreate    = require('./onCreate');
const getUsersToBeUpdated  = require('./getUsersToBeUpdated');

module.exports.onCreate = functions.database.ref('/Posts/{uid}/{postID}').onCreate(onCreate);
module.exports.getUsersToBeUpdated = functions.https.onRequest(getUsersToBeUpdated);

onCreate.spec.js

const onCreate = require('../onCreate');

let snapshot; 
let context;

beforeEach(() => {
    snapshot = {
        val: jest.fn()
    };

    context = {
        params: {id: 'ID_SOME_POST_ID'}
    };

});

test('that it should do something onCreate POST', () => {
    onCreate(snapshot, context);

    expect(snapshot.val).toHaveBeenCalled();
});

getUsersToBeUpdated.spec.js

const admin = require('firebase-admin');
const getUsersToBeUpdated = require(../getUsersToBeUpdated);

// we need to mock the funcionality of firebase-admin 
jest.mock('firebase-admin', () => {
    const admin = {};
    const snapshot = {
        data: jest.fn(() => ({propA: 'a', propB: 'b'}))
    };

    const admin.database = jest.fn(() => admin);
    const admin.doc = jest.fn(() => admin);
    const admin.get = jest.fn(() => Promise.resolve(snapshot));

    return admin;
});

let response;
let request;

beforeEach(() => {
    response = {};
    response.status = jest.fn();
    response.send = jest.fn();
    request = jest.fn();
});

// this function makes asynchronous requests so for simplicity Ill use async/await
test('that should return a successful request', async () => {
    await getUsersToBeUpdated(request, response);

    expect(response.send).toHaveBeenCalledWith({propA: 'a', propB: 'b'});
});

// this function makes asynchronous requests so for simplicity Ill use async/await
test('that should return a error request', async () => {
    const error = {code: 123, message: 'some error'};

    //force the get function to fail
    admin.get.mockReturnValueOnce(Promise.reject(error));

    await getUsersToBeUpdated(request, response);

    expect(response.status).toHaveBeenCalledWith(500);
    expect(response.send).toHaveBeenCalledWith(error);
});