Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Cloud Firestore(の、スタブ)を作ってみた / Stubbing Cloud Firestore
Hiron
December 08, 2017
Technology
1
560
Cloud Firestore(の、スタブ)を作ってみた / Stubbing Cloud Firestore
Mobile Act OSAKA #2で発表したスライドです。
Hiron
December 08, 2017
Tweet
Share
More Decks by Hiron
See All by Hiron
Swift on Windows ファーストインプレッション / Swift on Windows First Impression
hironytic
0
380
iPadOSDC: Multiple Windows
hironytic
4
1.9k
だったら、俺が代わりにやってやる / Swift Zoomin' Challenge
hironytic
0
100
SwiftのNeverとボトム型 / Never as a Bottom Type
hironytic
2
580
4000のワーニングと戦え!これは警告だ! / 4000 Warnings
hironytic
2
630
シンボリケート / Ore-con 2018 Summer
hironytic
3
810
全部iOSにしゃべらせちゃえ! / iOSDC 2018 LT
hironytic
3
950
ペダルのある生活 / The Pedal
hironytic
0
300
地方在住iOSエンジニアの生存戦略 / iOSDC 2017 LT
hironytic
1
4k
Other Decks in Technology
See All in Technology
AWSを使う上で意識しておきたい、クラウドセキュリティ超入門(駆け足版)
kkmory
0
230
金融領域のマルチプロダクトを効率よく開発・運用するためのシステム基盤と組織設計について / 2022-07-28-multi-product-platform
stajima
0
150
殺虫剤のパラドックスの真実 / The Truth of The Pesticide Paradox
kzsuzuki
1
210
テクニカルライティングの検定を受けてみた話 / "My Story About Taking the Technical Writing Exam
line_developers
PRO
1
230
Red Hat Enterprise Linux 9のリリースノートを読む前に知りたい最近のキーワードをまとめて復習
moriwaka
0
380
金融スタートアップの上場準備で大事にしたマインドセット / 2022-08-04-the-mindset-in-preparing-for-ipo
stajima
0
330
今 SLI/SLO の監視をするなら Sloth が良さそうという話
shotakitazawa
1
290
ソフトウェアアーキテクチャの基礎: Software Architecture in a Nutshell
snoozer05
31
9.2k
Simplify Cloud Native Security with Trivy
knqyf263
0
750
Reactコンポーネントにおけるテスト手法の選択肢
sakito
5
2k
セキュキャンを卒業してその後
kurochan
0
600
第22回 MLOps 勉強会:みてねのMLOps事情
tonouchi510
1
1.1k
Featured
See All Featured
GraphQLとの向き合い方2022年版
quramy
16
8.5k
Git: the NoSQL Database
bkeepers
PRO
415
59k
Gamification - CAS2011
davidbonilla
75
3.9k
GraphQLの誤解/rethinking-graphql
sonatard
31
6.8k
VelocityConf: Rendering Performance Case Studies
addyosmani
316
22k
Building an army of robots
kneath
299
40k
A better future with KSS
kneath
226
16k
Ruby is Unlike a Banana
tanoku
91
9.3k
Rebuilding a faster, lazier Slack
samanthasiow
62
7.3k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
100
6k
Raft: Consensus for Rubyists
vanstee
127
5.5k
Thoughts on Productivity
jonyablonski
44
2.4k
Transcript
Cloud Firestore を 作ってみた 2017/12/08 Mobile Act OSAKA #2 の、スタブ
About Me • Twitter、GitHub、Qiita、 SlideShare、Speaker Deck: ➡ hironytic • At
work: ➡ iOS (Objective-C)、 ときどき Android (Java)、 Windows UWP(C#) • At home: ➡ iOS (Swift) ひろん (一宮 浩教)
Firebase •Remote Config •App Indexing •Dynamic Links •Invites •AdWords •AdMob
•Analytics Develop Grow Earn •Cloud Messaging •Authentication •Realtime Database •Cloud Firestore (beta) •Storage •Hosting •Test Lab •Crash Reporting Oct.4, 2017 Mobile Act OSAKA #1
Cloud Firestore リアルタイムなデータ取得 サーバーとの通信も全部面倒見てくれる 使っている部分のテストどうしよう
そうだ スタブ、作ろう
スタブろう • スタブ (stub) とは、コンピュータプログラム のモジュールをテストする際、そのモジュール が呼び出す下位モジュールの代わりに用いる代 用品のこと。 引用元:Wikipedia 【スタブ】
ドキュメント • JSONライクなKey-Value • Swiftでは [String: Any] { "name": "Nobita",
"skill": "Hirune" }
コレクション • ドキュメントを含むコン テナ • コレクション内でユニー クなドキュメントIDで管 理される { "name":
"Nobita", "skill": "Hirune" } nvGvwR5 { "name": "Suneo", "skill": "Jiman" } zzD7UAv users
サブコレクション { "name": "general" } CSP36ah { "name": "random" }
CSP4CQz channels messages { "from": "AAd7UZv", "message": "何してますか?忙しいですか..." } MV5ahcO { "from": "nvGvwR5", "message": "昼寝してた" } MV5yaC0 { "from": "AAd7UZv", "message": "近くのコンビニエンスストアで..." } MV6Almn { "from": "nvGvwR5", "message": "まかせといてよ" } MV6L38V messages ...
データのリアルタイム取得 Firestore.firestore() .collection("users") .addSnapshotListener{ snapshot, error in // snapshot?.documents[0].documentID ...
String // snapshot?.documents[0].data() ... [String: Any] } コレクション
データのリアルタイム取得 Firestore.firestore() .collection("channels").document("CSP36ah") .collection("messages") .addSnapshotListener{ snapshot, error in // snapshot?.documents[0].documentID
... String // snapshot?.documents[0].data() ... [String: Any] } サブコレクション
データのリアルタイム取得 Firestore.firestore() .collection("users") .whereField("age", isGreaterThan: "18") .order(by: "age") .order(by: "name")
.addSnapshotListener{ snapshot, error in // snapshot?.documents[0].documentID ... String // snapshot?.documents[0].data() ... [String: Any] } クエリ
スタブりにくそう なので、 • すべての機能のスタブは作らない • 自分が必要なものだけ(なるべく妥協する) • Cloud Firestoreのインタフェースそのままでは やらない
どうやってスタブるか? Firestore App
DataStore どうやってスタブるか? Firestore App ある程度、操作を制限
どうやってスタブるか? DefaultDataStore Firestore StubDataStore App 通常時 テスト時 DataStore
コレクションの指定 protocol CollectionPath • コレクションを指す概念を抽象化 collection("channels") .document("CSP36ah") .collection("messages")
クエリ protocol DataStoreQuery • クエリを指定する概念を抽象化 • CollectionPathもDataStoreQuery(プロトコルを継承) collection("channels") .whereField("age", isGreaterThan:
"18") .order(by: "age") .order(by: "name")
クエリ=フィルタ+ソート collection("channels") .whereField("age", isGreaterThan: "18") .order(by: "age") [Entity] .filter(...) .sorted(...)
documentID: String data: [String: Any]
リアルタイムなデータ取得 DataStoreQueryにマッチするEntityの配列が リアルタイムに流れてくる
リアルタイムなデータ取得 DataStoreQueryにマッチするEntityの配列が リアルタイムに流れてくる RxSwiftのObservable func observeCollection(matches query: DataStoreQuery) -> Observable<[Entity]>
スタブるぞ • CollectionPathごとに Observableを保持しておく StubDataStore /channels /channels/CSP36ah/messages Observable<[Entity]> Observable<[Entity]>
/channels /channels/CSP36ah/messages Observable<[Entity]> Observable<[Entity]> スタブるぞ • DataStoreQueryに応じて、 フィルタ、ソートを行う Observableをmapで変換し て返す
StubDataStore filter(...) sorted(...) Observable<[Entity]> func observeCollection(matches query: DataStoreQuery) -> Observable<[Entity]> map
/channels /channels/CSP36ah/messages Observable<[Entity]> Observable<[Entity]> filter(...) sorted(...) Observable<[Entity]> map スタブるぞ •
元のObservableに更新が 流れれば、さっき返した Observableにも自動的に (リアルタイムに)更新 が流れる StubDataStore ✨ ✨
更新系メソッドも まるっとやれば
ほら、スタブれた ⭐ https://github.com/hironytic/CloudFirstoreStubPOC
まとめ • Cloud Firestoreのスタブを作った(スタブった) • 必要な操作にしぼってスタブりやすくした • RxSwiftのおかげでリアルタイムなデータ取得の部 分がうまいこといった •
作ったとは言ったが、使いものになるとは言って いない