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.gradle
のcom.android.tools.build:gradle
を3.0.1->3.2.1に変更。gradle wrapperのgradleのバージョンも古くて怒られたので4.1->4.10に変更。- そのあともいくつかBuild tools revisionのXXXがない!というのが出るのでその都度インストールするととりあえずビルドできる状態になる。
- あとは説明を読みながら順番に書いていけばとりあえず動くものは出来上がる。
- エミュレータで動作確認してたからかもしれないが、タップした後に鳴らす音の出始めを早くする(レイテンシを下げる)処理を書いたんだけど早くなった感じがしなかった。
- バックボタンでアプリを閉じても音が鳴り続けるので止める方法を知りたい。