1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AndroidQ以上でmockito-kotlinを使ったInstrumentationTestが動かない

Last updated at Posted at 2021-04-29

現象

Instrumentation TestでMockitoをKotlinで使うため、以下のようにライブラリを設定して使っていました。

app/build.gradle
    androidTestImplementation 'org.mockito:mockito-core:3.9.0'
    androidTestImplementation ('org.mockito.kotlin:mockito-kotlin:3.1.0'){
        exclude group: 'org.mockito', module: 'mockito-core'
    }
    androidTestImplementation ('com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.1'){
        exclude group: 'org.mockito', module: 'mockito-core'
    }

ところが、P(Android9)の端末(エミュレーター)では問題なく動作するのに、Q以上(Android10)以上の端末orエミュレーターで動かそうとするとモックに失敗してしまいました。

エラーメッセージ

java.lang.NullPointerException: Attempt to invoke interface method 'boolean org.mockito.plugins.MockMaker$TypeMockability.mockable()' on a null object reference
at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:23)
at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:250)
at org.mockito.internal.creation.MockSettingsImpl.build(MockSettingsImpl.java:232)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:61)
at org.mockito.Mockito.mock(Mockito.java:1951)
at org.mockito.Mockito.mock(Mockito.java:1862)

解決方法

どうやら64bitライブラリが問題?なようで、以下の設定を行うと解消しました。

androidTest用のマニフェストファイルを作成する

androidTest下に、AndroidManifest.xmlを作成し、以下のように記述します。

androidTest/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.package">

    <application android:extractNativeLibs="true" />
</manifest>

これだけで、テストが通るようになりました。

解決方法に辿り着いた経緯

mockito-kotlinが使えないなら、MockKを使ってみようと思い変更したのですが、やはり同じで、Android Pでは動いて、Q以上では動かない。
ただしエラーメッセージは異なっていました。

Caused by: io.mockk.proxy.MockKAgentException: MockK could not self-attach a jvmti agent to the current VM. This feature is required for inline mocking.
This error occured due to an I/O error during the creation of this agent: java.io.IOException: No such file or directory

Potentially, the current VM does not support the jvmti API correctly
at io.mockk.proxy.android.AndroidMockKAgentFactory.init(AndroidMockKAgentFactory.kt:63)
at io.mockk.impl.JvmMockKGateway.<init>(JvmMockKGateway.kt:46)
at io.mockk.impl.JvmMockKGateway.<clinit>(JvmMockKGateway.kt:172)

このメッセージでググって、辿り着いたのが以下のissue.

ここで64bit向けのライブラリがapkにないせいではないかと指摘されており、コメントで提案されていた案の1つを試してみたところ上手くいきました。
そこで、mockito-kotlinに戻してみて同じように設定し、テストを動かしてみたら無事に動いた、というわけです。

android:extractNativeLibsについて

こちらのページによれば、android:extractNativeLibsはデフォルトでtrueらしいのですが、Instrumentationテスト実施時には違う、ということでしょうか。。。

(でも、実機は説明付くんだけど、エミュレーターのimageはx86で、x86_64じゃないんだけどな・・・・動かしているマシンが64bitだからそちらに引っ張られるんだろうか?)

追記
AGP(Android Gradle Plguin)3.6.0から、デフォルトはfalseに変わったようです。

mockito-kotlinとMockKを同時に使う方法

MockKに置き換える際、いっぺんに変えるのは無理だったので単純なテストだけ置き換えたのですが、その際、mockito-kotlinとMockKに単純に同時に依存するとテストが実行出来ませんでした。
(エラーメッセージは忘れてしまいましたが、ビルドの時点で失敗したと思います)

以下のサイトが参考になりました。
https://medium.com/monsterculture/how-to-use-mockito-together-with-mockk-in-android-instrumentation-tests-c8d022fac04e

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?