Firebase функционирует офлайн тестовая заглушка - PullRequest
0 голосов
/ 30 мая 2018

Я пишу тест для функции триггера onWrite для базы данных Firebase в автономном режиме, используя заглушки, как предложено в документации и в примере github .

Но я запутался, как поставить несколько .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), а затем существует множественный доступ кбазы данных.

Так есть ли простой способ заглушить все эти вызовы?Или заглушка хороша только для функций, которые имеют простые данные и имеют меньший доступ для чтения к базе данных?

PS: я также использовал тестирование в онлайн-режиме, но это изменяет состояние базы данных, которое я не могу восстановить тогда

1 Ответ

0 голосов
/ 30 мая 2018

Тестирование функций с помощью firestore - дело непростое.Я потратил много сил, чтобы попробовать разные шаблоны, и в итоге получил эту стратегию.

  1. Создание в вашем проекте универсальных методов для извлечения данных.Например, функция с именем collectionQuery, docQuery и т. Д.
  2. Инициализируйте проверку функций в онлайн-режиме.(таким образом, ваши тесты не будут бесконечно жаловаться на то, что их не заглушают и не высмеивают :))
  3. Теперь в ваших тестах вы можете просто следить за своими функциями с шага 1. Если вы создаете функции, чтобы онивозвращать значения становится очень просто.

Пример функции collectionQuery (машинопись):

/**
 * 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.

Дайте мне знать, если это поможет :)

...