Firestoreのデータをcopy/exporrt/importできるfsrplを使ってunit testを書く
こんにちは。もぐめっとです。
皆さんは上記を見てなにか叫びたくなりませんか?
是非その叫んだ内容をコメント欄で書いて答え合わせしましょう。
みなさん、fsrplというコマンドを知ってますか?
firestoreのデータをイジイジできるコマンドなんですけど、これが最近気づいたらリリース版になっていて、reference型が対応してなかったのがとうとう対応して超神コマンドと化してしました。
fsrplがいつの間にかreference型にも対応してた。とても使えるツールだとおもいます。データのコピペとかimport/exportとかに是非みなさん使ってみるといいと思います!テストデータいれるのにちまちまとコンソールから入れる作業からおさらば!! #firebase #firestorehttps://t.co/UVJ23HZzOq
— もぐめっと@だいき (@mogmet) October 9, 2020
今回はfsrplを使ってセキュリティールールのunit testを書いてみたのでご紹介です。
fsrplの使い方
READMEにわかりやすく書いてあるので詳細はそちらに譲るとして、大体の使い方とコマンドだけ転載いたします。
インストール
brew tap matsu0228/homebrew-fsrpl
brew install fsrpl
事前準備として最初に環境変数で、firebaseの秘密鍵のjsonのパスを指定しておきます
export FSRPL_CREDENTIALS=./path/to/adminsdk.json
コピーする時
fsrpl copy [コピー元のドキュメントを指定] --dest [コピー先のドキュメントを指定]
exportする時
fsrpl dump [コピー元のドキュメントを指定] --path [バックアップファイルを保存するディレクトリを指定]
importする時
fsrpl restore [コピー元のドキュメントを指定] --path [復元対象のJSONファイルを指定]
security ruleのunit testを書く
npmで環境を整えます。こんな感じ。
{
"scripts": {
"test": "tsc && FIRESTORE_EMULATOR_HOST=localhost:8080 FIREBASE_DATABASE_EMULATOR_HOST=localhost:9000 npx jest",
"watch": "npm test -- --watch",
"emulator:start": "firebase emulators:start --only firestore",
},
"devDependencies": {
"@firebase/app-types": "^0.6.1",
"@firebase/firestore-types": "^1.13.0",
"@firebase/rules-unit-testing": "^1.0.7",
"@types/chai": "^4.2.13",
"@types/jest": "^26.0.14",
"filesystem": "1.0.1",
"jest": "^26.5.2",
"jest-environment-uint8array": "^1.0.0",
"mocha": "^8.1.3",
"source-map-support": "0.5.19",
"ts-jest": "^26.4.1",
"ts-node": "9.0.0",
"tslint": "^6.1.3",
"typescript": "^4.0.3"
},
"dependencies": {
"firebase-admin": "^9.2.0",
"jest-environment-node": "^26.0.1"
}
}
FIRESTORE_EMULATOR_HOSTで環境変数をセットておくのが味噌です。
FIREBASE_DATABASE_EMULATOR_HOSTはセットしておかないと警告出てうるさかったので使わないけどセットしておきました。
そしてテストはこんな感じで実装できました
import TestProvider from "./TestProvider"
import { execSync } from "child_process";
import * as firebase from "@firebase/rules-unit-testing"
const provider = new TestProvider()
const projectId = "hoge"
const uid = "d5CsSU2fXhUtRx8JqKBbqREVq883"
const clientFirestore = firebase.initializeTestApp({ projectId, databaseName: "dbName", auth: {uid: uid} }).firestore()
const emulatorHost = process.env.FIRESTORE_EMULATOR_HOST
describe('test', () => {
afterEach(async () => {
await firebase.clearFirestoreData({projectId: projectId})
})
// users
describe("users collection tests", () => {
describe("read", () => {
test("認証してれば読み取れる", async () => {
const dataPath = "users/*"
const mockPath = "./mock/users"
const restoreCmd = `FIRESTORE_EMULATOR_HOST=${emulatorHost} fsrpl restore "${dataPath}" --path "${mockPath}" --debug --emulators-project-id=${projectId}`;
const stdout = await execSync(`${restoreCmd}`);
console.warn(`imported test data to ${dataPath}: ${stdout.toString()}`);
await firebase.assertSucceeds(clientFirestore.doc(`users/${uid}`).get())
})
})
})
})
execSyncを通してfsrplを実行することで簡単にテストデータが用意できます!素敵!
テストを実行するときはエミュレータを予め実行しておきます。
npm run emulator:start
別ターミナルでテストを実行。
npm run test
@mogmetの所感
今までは頑張ってコードで書いてデータを準備してましたが、fsrpl使えばjsonでモックデータを準備しておくだけで簡単にテストがかけそうです。
cloud functionsのunit testの時とかに特に重宝するんじゃないかと思います。
欠点をいうと、security ruleでは書き込みの時のテストの時にmockのデータを使いたい感じになると思うんですけど、fsrplだとセキュリティールール通さず直に書き込んでしまってテストにならないので、一回fsrplでロードした後、データをgetして、getしてきたデータを使って書き込みテストするとかになるのかなぁとか構想してますが、なんか二度手間感があるので他にいい方法ご存じの方いたら教えて下さい。
ただ、テスト以外にもコンソールでfirestoreのデータをポチポチ準備するのはつらいんで、積極的にこのコマンドを使ってデータを準備できればと思いました!
Author And Source
この問題について(Firestoreのデータをcopy/exporrt/importできるfsrplを使ってunit testを書く), 我々は、より多くの情報をここで見つけました https://qiita.com/mogmet/items/8c6ccd8df61e5b6db64d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .