アプリ開発の記録

ちょっとした夏の連休が終わった。ReactNativeのアプリ開発を始めて約1か月弱。まだまだ完成には程遠いけれども、ベースとなる機能は少しづつ出来上がってきた。

アーキテクチャとテスト可用性

先日、なんちゃってドメイン駆動設計(DependencyInjection + Entity + Service)に移行したことでテストが書きやすくなったので、データベース部分もJestを使って単体テストを書き始めた。DIとDIを支える仕組みを用意した効果の寄与が大きいと思う。ServiceはUseCaseも含め、全てServiceと呼んでいる。そのうち破綻するかもしれないけど機能単位でモジュールを切り分けしているのでコードは分かりやすい。

モジュールの単体テスト

モジュールが増えたことで、テスト対象も増えた。まだカバレッジは10%くらいで、SQLで木構造を扱う部分しか重点的に書いていない。モジュールを分けたらテストも増えるよね。きちんとやるのはやっぱり大変。

「Service」→「DTO」→「DAO」→「MigratedDB」→「Database」

test vs test.tsx

テストを別フォルダに入れるか、それともモジュールの横に書くかという話があるのだが、この二つは両立すると気づいた。モジュールの単体テストは近くに置き、結合テストのような複数モジュールを扱うテストは独立したフォルダで管理する。

データベース周りの話

初めにIDatabaseを継承したDesktopSQLiteDBクラスを作成した。作り始めた頃はReact-native-sqlite-storageのAPIがデスクトップ版と異なるためモックできないと思っていたが、開発で実際に使うAPIは一つだけだったので、そのAPIを再現したら上手くいった。モックを作ると「このモックは正しく動くの?」と不安になるものだが、実機の上でしか動かないテストを単体テスト環境でも実行したところ、一発で動いたのでヨシ!ってなった。DI強い。

DIが特に重要なケースって「データベース」「ファイルIO」「ネットワーク」「ドライバ」などだろうか。

データベースの処理は非同期なので、テストも非同期処理ばかりになる。今まで書いてきたTypescriptの中でも一番awaitを多用してる。async/awaitが無い時代、これをどうやって管理していたのか想像すらできない。

SQLはまだまだ苦手。SQLでツリー構造とか分けわからん。データ更新時にデータの整合性をとるために再帰的な更新が発生する(ようなアプリケーションを作っている)。SQLで1発で更新できそうな気もするけど、多分保守できなくなるのでクエリを投げまくって無理やり解決している。

単体テストの話

Jestで非同期処理をテストする方法は知らないとハマりがち。正しいか分からないけどこんな風に書いてる。あとはVSCodeでデバッガが使えれば最強なんだけどまだ成功していない(それが必要なところまでまだ作っていない)

it('get roots', async () => {
    await expect((async () => {
    const fcs = await dao.getRoots();
    expect(fcs.length).toBe(2);
    })()).resolves.not.toThrow();
})

言語

痛い目には合っていないけど、javascriptのDateの罠を踏んだ。罠が多い事はなんとなく知っていたけど実際に踏んだのはこれが初めて。new Date(2020, 8, 16)って書いたら'2020-08-16'になると思うよね。

グラフ

いつ触っても面倒なグラフライブラリ。再利用を考えなければなんとかなるよーな。