Firebase功能脱机测试存根

时间:2018-05-30 05:40:12

标签: unit-testing firebase google-cloud-functions sinon

我正在使用文档和github sample中建议的存根在脱机模式下编写firebase数据库onWrite触发器函数的测试。

但我很困惑如何在触发器的数据中存储多个.child().val()的值。以下是我创建数据对象的进度:

let data={
            before: {
                val : ()=> null,

            },

            after:{
                val: ()=> {/*after data here */},
                child: {
                    "child1": "How have value here from val",
                    "child2": "How have value here from val"
                }
            }
        }

由于我的函数有点复杂,因此从传入数据(2到3级嵌套)中有很多值读取,然后还有多个数据库访问权限。

那么有没有简单的方法来存根所有这些电话?或者,存根只适用于具有简单数据和较少数据库读取权限的函数?

P.S:我也使用了在线模式测试但是改变了我无法恢复的数据库状态

1 个答案:

答案 0 :(得分:0)

使用firestore测试函数并不容易。我已经用了很多精力来尝试不同的模式,并最终采用了这种策略。

  1. 在项目中创建通用方法,以提取数据。例如,名为collectionQuerydocQuery等的函数
  2. 在线模式下初始化功能测试。 (这样你的测试就不会无休止地抱怨没有被诅咒和嘲笑的东西:))
  3. 现在,在您的测试中,您可以简单地从第1步监视您的功能。如果您创建了这些功能,以便它们返回值,那么它就变得非常简单了。
  4. collectionQuery函数(typescript)的示例:

    /**
     * The purpose of this relatively simple function is to query firestore!
     * By wrapping the operation in a helper function, it becomes much easier to test.
     * @export
     * @template T Provide the variable type for the function
     * @param {FirebaseFirestore.Firestore} afs The firestore instance, usefull for switching between functions/admin
     * @param {FirebaseFirestore.Query} query The query to perform. By accepting a query, it becomes very flexpible
     * @returns {Promise<Array<T>>} The result as an array
     */
    export async function collectionQuery<T>(afs: FirebaseFirestore.Firestore, query: FirebaseFirestore.Query): Promise<Array<T>> {
        try {
            if (afs == null || query == null) {
                throw new Error(`You must provide an firestore instance, or a query`);
            }
            const snapshot = await query.get();
            const returnData: T[] = snapshot.docs.map((doc) => doc.data() as T);
            return returnData;
        } catch (error) {
            throw new Error(`collectionQuery failed unexpected with: ${error.message}`);
        }
    } 
    

    好处是在单元测试中,我现在可以简单地监视这个功能。我正在使用Jest,所以像这样:

    jest.spyOn(firehelpers, 'collectionQuery').mockReturnValue([]} // simulate no data returned by query
    jest.spyOn(firehelpers, 'collectionQuery').mockReturnValue([{foo: 'bar'}]} // One result returned
    

    此策略可以轻松测试读取和写入db / firestore的函数。如果需要,也可以与firebase库上的存根结合使用。

    让我知道它是否有帮助:)