# #javascript #firebase-authentication #google-cloud-functions #firebase-tools
Вопрос:
У меня работают эмуляторы базы огня.
Мое приложение может вызвать облачную функцию firebase, которая может создать пользовательское утверждение пользователя, если это разрешено пользователю (в зависимости от значения в базе данных).
Я пытаюсь вызвать эту функцию:
import * as firebase from '@firebase/testing';
import * as fs from 'fs';
const app = firebase.initializeTestApp({
databaseName: 'mydb',
auth: {
uid: 'useruid'
},
});
describe('Firebase Functions', () => {
beforeEach(async () => {
await firebase.loadDatabaseRules({
databaseName: 'mydb',
rules: fs.readFileSync('database.rules.json', 'utf8'),
});
});
afterAll(async () => {
await Promise.all(firebase.apps().map((app) => app.delete()));
});
const cloudfunction = app.functions().httpsCallable('cloudfunction')
it('throws error if user is not authenticated', async () => {
await firebase.assertFail(cloudfunction())
})
});
Это приводит к ошибке:
Ошибка: Ошибка: В ответе на предполетный запрос неверный код состояния HTTP 404
Ответ №1:
На мой взгляд, вам не нужно вызывать firebase из вашего модульного теста, потому что это не ваше дело, правильно ли работает firebase или нет, вам нужно проверить свою бизнес-логику, чтобы это означало, что вы будете издеваться над методом, который вызывает firebase, и проверять ожидаемые возвращаемые значения этого метода, например, вы можете написать 2 случая, когда уведомление будет отправлено без ошибок, и во-вторых, если служба firebase вернет сбой, для этих 2 случаев ваш код должен иметь соответствующее поведение. Тестирование службы firebase будет проводиться командой, работающей на базе firebase
Комментарии:
1. Я пишу интеграционные тесты. Мои другие тесты уже взаимодействуют с базой данных, издевающейся над эмуляторами Firebase, почему бы и не использовать функции? Я тестирую весь поток end2end, например, пользователь может нажать кнопку в пользовательском интерфейсе, которая вызывает функции firebase, которые изменяют данные в базе данных, если у пользователей есть правильные разрешения. Я могу модульно протестировать каждый шаг, но я также хотел бы протестировать все поведение, чтобы убедиться, что между каждым шагом нет ошибок.
2. Просто в любом случае вы можете имитировать метод firebase, я имею в виду, что вы можете протестировать firebase вручную, когда будете создавать приложение, но в процессе разработки я считаю более разумным имитировать и тестировать ваши коды,
3. Даже если вы разработчик firebase, вы должны протестировать firebase изнутри firebase, а из внешнего приложения вы должны просто издеваться и смотреть на все случаи, когда эта служба вернет некоторые сбои или успех, вы должны ожидать, что все случаи
4. В противном случае вы хотите проверить, правильно ли вы обратились к этой службе или нет, но для этой службы есть библиотеки и документация, это непроверяемая часть кода, в модульных тестах и в интеграционных тестах вы можете проверить свою локальную бизнес-логику
5. Я понимаю вашу точку зрения, но это не решает проблему. На данный момент я буду издеваться над своими функциями, но для @firebase/testing не имеет смысла не поддерживать вызов эмуляторов облачных функций, когда это работает для базы данных.
Ответ №2:
Для этого существует тест firebase-функций. Это позволяет вам оборачивать облачные функции и вызывать их напрямую, а также создавать заглушки для обновлений документов. При запуске в контексте эмулятора пакет SDK firebase-admin по-прежнему взаимодействует с эмулятором. Базовая настройка может выглядеть следующим образом (при условии наличия машинописного текста)::
// functions/src/test/functions.test.ts
import {expect} from "chai";
import "mocha";
import firebaseFunctionTest from "firebase-functions-test";
import * as cf from "../index";
const projectId = "demo-project";
const test = firebaseFunctionTest({
projectId,
});
after(() => test.cleanup());
describe("cloud functions", () => {
afterEach(async () => {
await test.firestore.clearFirestoreData(projectId);
});
describe("myFunction", () => {
const myFunction = test.wrap(cf.myFunction);
// Create mock data with the admin SDK and test function.
}
}
В вашем package.json
вы можете поместить сценарий, подобный.
"scripts": {
"test:unit": "mocha -r ts-node/register --timeout 5000 --exit src/**/*.test.ts",
"test": "npm run build amp;amp; npx firebase -P demo-project emulators:exec 'npm run test:unit'",
...
}
Возможно, вы также захотите взглянуть на https://github.com/firebase/quickstart-testing/tree/master/unit-test-cloud-functions
и https://firebase.google.com/docs/functions/unit-testing.
Комментарии:
1. Это предназначено для тестирования облачной функции. Я хочу протестировать свое веб-приложение, которое вызывает эту функцию. Я не могу
import * as cf from "../index";
, так как облачная функция объявлена в отдельном проекте.2. Ладно, я неправильно это понял. Не могли бы вы запустить эмулятор в отдельном проекте и подключить проект, который вы хотите протестировать, к этому эмулятору?
3. Проблема в том, что вы не можете вызвать облачную функцию, запущенную в эмуляторе, из модульного теста с использованием
@firebase/testing
библиотеки. Я прибегнул к простому издевательству над функцией базы данных в модульном тесте моего приложения