Firebaseを無料Planで使うため, Unit Testで帯域を消費したくない.
Firebaseをローカルサーバで用意して, それと通信することでこれを回避する.
Robolectric(JVM)で試そうとしたが, サーバからonComplete
の応答が受け取れず, 現状Instrumentation Unit Test
で試している.
Local Firebase Server
e2eのシナリオテスト用には十分なFirebase ServerがNode moduleとして提供されているのでそれを利用する.
npm install --save-dev firebase-server
firebase serverを起動するjsを用意する. ファイル名はlaunch_local_firebase.js
とでもしておく.
var FirebaseServer = require('firebase-server');
FirebaseServer.enableLogging(true);
new FirebaseServer(5000, 'test.firebase.localhost', {
/* You can put your initial data model here, or just leave it empty */
});
Firebaseはホスト名にドットを2つ含んでいる必要があるためlocalhost:5000
では接続できない.
Local Firebase serverはtest.firebase.localhost
として起動する.
Local Firebase Serverへの要求/応答をロギングするためにenableLogging(true)
を指定しておくと便利.
ホストPCのhostファイルにtest.firebase.localhost
を127.0.0.1
つまりlocalhostで接続できるように次の一行を追記する.
Macであれば/private/etc/hosts
あたりにホストファイルがある.
127.0.0.1 test.firebase.localhost
あとは先ほど作成したlaunch_local_firebase.js
を起動する.
node launch_local_firebase.js
これでLocal Firebase Serverの準備は完了.
Run AndroidTest
あとはAndroidからFirebaseへ接続するだけでよい. 接続先はローカルホストになるため,
new Firebase("ws://test.firebase.localhost:5000/");
としていする. ただしGenymotionはlocalhostに固有のIPが割り当てられているため下記とする必要がある点に注意.
new Firebase("ws://192.168.56.1:5000/");
RobolectricでFirebaseからのコールバックが発火しない問題があり渋々Instrumentation Test
で実行しているが, 解決方法をご存知の方はご教授頂けると幸いです.
ちなみに, 簡易な確認でよければofflineモードでテストをパスする方法もあるが, 信用性の面で採用しなかった.
public static class DebugModule extends Module {
public DebugModule(Context context) {
super(context);
}
@Override Firebase provideFirebase() {
Firebase.setAndroidContext(context);
Firebase firebase = new Firebase(FirebaseConstant.DEBUG_URI);
firebase.goOffline();
return firebase;
}
}
以上.