1

AndroidStudio で作業します。PowerMock で AndroidInstrumentalTest の final クラスのモックを作りたい。gradle に追加されたライブラリ:

 androidTestCompile ('org.powermock:powermock-api-mockito:1.5.6')
 androidTestCompile ('org.powermock:powermock-core:1.5.6')
 androidTestCompile ('org.powermock:powermock-module-junit4:1.5.6')
 androidTestCompile 'org.mockito:mockito-core:1.10.8'
 androidTestCompile 'com.google.dexmaker:dexmaker:1.1'
 androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.1'

テスト クラスを作成します。

public class BluetoothTest extends ActivityInstrumentationTestCaseWithLogIn<PlanActivity> {


 public BluetoothTest() {
    super(PlanActivity.class);
 }


  @Override
  public void setUp() throws Exception{
        super.setUp();          
        BluetoothGatt gatt = PowerMockito.mock(BluetoothGatt.class);
  }
}

スタックトレース:

 java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils
at org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167)
at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217)
at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117)
........
at android.support.test.internal.runner.junit3.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
........
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:270)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1732)

この問題の解決策を確認しましたが、うまくいきませんでした。どうやらソリューションは、powermock ではなく、mockito-core に役立ちます。それは別の問題で証明された

docsを見た後、テスト クラスに @RunWith(PowerMockRunner.class) および @PrepareForTest(BluetoothGatt.class) のアノテーションを追加してみます。結果 :

   java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
    at org.powermock.modules.junit4.common.internal.impl.JUnitVersion.getJUnitVersion(JUnitVersion.java:28)
    at org.powermock.modules.junit4.common.internal.impl.JUnitVersion.isGreaterThanOrEqualTo(JUnitVersion.java:23)
    at org.powermock.modules.junit4.PowerMockRunner.getRunnerDelegateImplClass(PowerMockRunner.java:38)
    at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:33)
   ........
    at org.junit.runner.Computer.getSuite(Computer.java:26)
    at android.support.test.internal.runner.TestRequestBuilder.classes(TestRequestBuilder.java:598)
    at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:578)
    at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:542)
    at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:269)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1732)
4

2 に答える 2

1

ルート化されていないデバイスでは、APK は「検証」の対象となります。VM は、クラスがコンパイル対象の実装のみを参照することを保証します。エミュレーターとルート化されたデバイスは、このルールの対象ではありません。

残念ながら、クラスローダー (PowerMock および Robolectric) をハッキングする実装は、(それらをモックするために) 予期しない静的クラスおよびメソッドの実装を作成するため、ほとんどの場合、その規則に違反します。

インストルメンテーション テストではなく、クラスローダーのハッキングを JVM 単体テストに保持し、代わりに、関連するインターフェイスを制御 (およびモック) できるラッパーに抽出します。

于 2015-03-30T16:15:46.603 に答える