fresh digitable

めんどくさかったなってことを振り返ったり振り返らなかったりするための記録

JavaとKotlinが混在するプロジェクトでmockitoをmockKで少しずつ置き換えていく

前提

  • Javaのプロジェクトに徐々にKotlinのコードを増やしていっている
  • Javaのテストコードではmockitoを使ってモックオブジェクトを作成していた
  • テスト対象のクラスに注入するクラスがKotlinに変わった
  • Kotlinのクラスはmockitoではそのままモックできないのでなんかやる必要がある
  • mockitoの設定をなんかやるよりはmockKを入れてテストコードをKotlinにする方を頑張ったほうがよさそうと判断して、テストコードをKotlinにすることにした
  • JUnit5やSpek2の時代が来そうなのでその前に書いて供養したかった

方針

  • かといってテストクラスを全部書き換えるのは大変
  • 書き換えたいのはモックを作るところだけ
  • モックを作る処理を抽象化して、テストクラスからはどんなモックライブラリを使っているのか意識しなくてもよいようにしてしまう
  • テスト対象の生成はTestRuleの中で行なっており、そこでモックも一緒に作成していたので、TestRuleをそのままモックライブラリのラッパーとして使うことにした
    • TestRuleのプロパティにアクセスできる別のPageObject的なクラスに移譲しても良かったかも

どうやったか

  • テストクラスの静的な内部クラスとして実装していたTestRuleだけをktファイルに移動させてKotlin化
  • mockitoをmockKに置き換え
  • verifyとかのモック用アサーションTestRuleクラスに移行して、さらにmockKに置き換え
    • モックの生成を一回だけにしたかったらcompanion objectの中で生成するといいかも。その場合はfinishedとかで忘れずにclearMocks()をやる
  • 公式にTruthを入れる動きがあるのでアサーションライブラリのクラスも隠蔽しておくといいかも

おまけ

  • こんな感じにするとほぼすべての行がrule.から始まったりしてテストコードとしては何となく微妙
  • Kotlinのテストクラスならwith(rule) {}で消せる

これが

fun test() {
  // setup
  rule.setupHoge(args = 42, returns = true)

  // exercise
  rule.testTarget.hoge(42)

  // verify
  rule.verifyHogeRepositoryIsCalled(args = 42)
  assertThat(rule.testTarget.isVisibleHoge.get()).isTrue()
}

こう

@Test
fun test(): Unit = with(rule) {
  // setup
  setupHoge(args = 42, returns = true)

  // exercise
  testTarget.hoge(42)

  // verify
  verifyHogeRepositoryIsCalled(args = 42)
  assertThat(testTarget.isVisibleHoge.get()).isTrue()
}

(2019/4/2 修正) IDEのラベルが荒ぶるので戻り値を書いている。 Unitを返すメソッドじゃないとテストが実行できないようなので、: Unitは念の為書いておく方が良い(少なくともこの例では必須)。

asciidocで書いたドキュメントをgradleでpdfにビルドする設定

adocで書いていたドキュメントをgradleでpdfにビルドできるように色々やりました。今回のミソはjrubyのgradle pluginを使うとgemを使えるようになるということです。

asciidoctorのプラグインと依存関係のgemを使えるようにするために、次のプラグインをプロジェクトルートのbuild.gradleのdependenciesに追記する。

classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.9.2'
classpath 'com.github.jruby-gradle:jruby-gradle-plugin:1.6.0'

gemを読み込んだりasciidoctorタスクの設定を行ったりする。PlantUMLで図を描いているので、これをPDFに入れるためにasciidoctor-diagramを入れている。これの画像を出力するディレクトリをちゃんと指定しないとPDFに正しく画像が差し込まれない。いい感じのディレクトリレイアウトを知りたい。

また、日本語環境で改行をいい感じにするためにasciidoctor-pdf-cjkを入れている。

apply plugin: 'org.asciidoctor.convert'
apply plugin: 'com.github.jruby-gradle.base'

dependencies {
  gems 'rubygems:asciidoctor-diagram:1.5.9'
  gems 'rubygems:asciidoctor-pdf:1.5.0.alpha.16'
  gems 'rubygems:asciidoctor-pdf-cjk:0.1.3'
}

asciidoctor {
  dependsOn jrubyPrepare
  requires = [
    'asciidoctor-diagram',
    'asciidoctor-pdf-cjk'
  ]
  gemPath = jrubyPrepare.outputDir

  sourceDir = file('docs')
  sources {
    include 'toc.adoc'
   }

  backends = ['pdf']
  outputDir = file('docs/output')
  separateOutputDirs = false
  attributes = [
    'imagesoutdir': 'art', // docs ディレクトリから見た相対パス
    'imagesdir': 'art'
  ]
}

oboeのコードラボをやった時のメモ

かねてより気になっていたoboeのコードラボをやってみた。とりあえず最後まで流してみたという程度で、詳しい動きは追えていない。そこまでのメモということで何卒ご容赦を。

Build a Musical Game using Oboe

  • IllegalStateException: Failed to find Build Tools revision 26.0.2 とか言われる。SDKツール26.0.2をインストールする。
  • RuntimeException: No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android とか言われる。mips64...?となってすこし調べたところbuild toolが古いのが原因なのではないかと考えてsamples/build.gradlecom.android.tools.build:gradleを3.0.1->3.2.1に変更。gradle wrapperのgradleのバージョンも古くて怒られたので4.1->4.10に変更。
  • そのあともいくつかBuild tools revisionのXXXがない!というのが出るのでその都度インストールするととりあえずビルドできる状態になる。
  • あとは説明を読みながら順番に書いていけばとりあえず動くものは出来上がる。
  • エミュレータで動作確認してたからかもしれないが、タップした後に鳴らす音の出始めを早くする(レイテンシを下げる)処理を書いたんだけど早くなった感じがしなかった。
  • バックボタンでアプリを閉じても音が鳴り続けるので止める方法を知りたい。