1

Работа в AndroidStudio. Хотите сделать макет финального класса для AndroidInstrumentalTest с помощью PowerMock. Добавлены ЛИЭС в 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) 

Я проверил решения от this вопроса, не повезло. По-видимому, решения помогают с mockito-core, а не с powerermock. Это подтверждается another issue

Я увидел 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) 
+0

возможно дубликат [Использовать Mockito-ядра для создания издеваться над окончательным класс?] (http://stackoverflow.com/questions/29315029/use-mockito-core-for-create-mock-of-final-class) –

ответ

1

На некорневых устройствах, APK-подлежит «проверку», где VM гарантирует, что классы относятся только к реализации они скомпилированных. Эмуляторы и корневые устройства не подчиняются этому правилу.

К сожалению, реализации, которые взломают загрузчики классов (PowerMock и Robolectric), почти всегда нарушают это правило, потому что они создают неожиданные статические классы и методы реализации (для их издевательства).

Храните взломщик класса в своих модульных тестах JVM, а не ваши контрольные тесты, и вместо этого извлекайте любые соответствующие интерфейсы в оболочку, которую вы можете контролировать (и макет).

1

Вы пытались использовать Robolectric + Mockito?.

Я считаю, что у вас есть правильная идея. Это должно быть так же просто, как:

BluetoothGatt gatt = mock(BluetoothGatt.class); 

Пожалуйста, обратите внимание на этот пример:

import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.times; 
import static org.mockito.Mockito.verify; 
import static org.mockito.Mockito.when; 

private BluetoothGattCharacteristic characteristic; 
private OnBoardingService service; 
private BluetoothGattReceiver receiver = new BluetoothGattReceiver(); 

@Before 
public void initialise() { 
    BleDevice bleDevice = mock(BleDevice.class); 
    when(bleDevice.getType()).thenReturn(BleDeviceType.WunderbarMIC); 
    BluetoothGatt gatt = mock(BluetoothGatt.class); 
    BluetoothGattService gattService = mock(BluetoothGattService.class); 
    when(gatt.getServices()).thenReturn(Arrays.asList(gattService)); 
    when(gattService.getUuid()).thenReturn(fromString("00002001-0000-1000-8000-00805f9b34fb")); 
    characteristic = mock(BluetoothGattCharacteristic.class); 
    when(gattService.getCharacteristics()).thenReturn(Arrays.asList(characteristic)); 

    service = new OnBoardingService(bleDevice, gatt, receiver); 
} 

Источник: https://github.com/relayr/android-sdk/blob/master/tests/src/androidTest/java/io/relayr/ble/service/OnBoardingServiceTest.java https://github.com/relayr/android-sdk/blob/master/tests/src/androidTest/java/io/relayr/ble/service/BluetoothGattReceiverTest.java