Android инструментальный тест, пробные финальные классы - PullRequest
0 голосов
/ 09 января 2019

Как смоделировать финальные классы внутри инструментированных тестовых случаев Android, то есть, имитировать финальные классы внутри Android Run Time?

(я использую Mockito 2.X)

У меня есть тестовый пример, подобный следующему -

import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    // This is my app specific NON - Final class
    private ShutdownServicesReqSig rebootSig = ShutdownServicesReqSig.newBuilder(ShutDownType.REBOOT_SYSTEM).setReason("test").build();

    private PowerManager mockedPowerManager = null;

    private Context mockedContext = null;


    @Test
    public void testRestart() throws InterruptedException
    {

        mockedContext = Mockito.mock(Context.class);

        mockedPowerManager = Mockito.mock(PowerManager.class);  // Here is the problem android.os.PowerManager is a Final class in latest Android SDK
                                                        // I need to mock it, only then I can use Mockito.verify() on PowerManager

        Mockito.when(mockedContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mockedPowerManager);

        assertTrue(executor.requestShutdown(rebootSig));

        Thread.sleep(1000);

        Mockito.verify(mockedPowerManager).reboot(any(String.class)); // Mocking of PowerManager is essential to be sure of method call on PowerManager, using Mockito.verify 

        Mockito.reset(mockedPowerManager);
    }
}

Когда я запускаю его как Android Instrumented Test на ART (размещение внутри - MyApplication\app\src\androidTest), я получаю следующую ошибку -

org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class android.os.PowerManager
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types

Но тот же код, когда я работаю как обычный тест JUnit, внутри JVM (помещая внутрь - MyApplication\app\src\test) работает отлично.

Мне нужно запустить его внутри ART, так как мне нравится тестировать некоторые из моих настроенных служб Android, и мне нужно смоделировать финальные классы, такие как PowerManager, так как только тогда я смогу использовать Mockito.verify() на PowerManager , чтобы проверить определенные вызовы методов на PowerManager.

Помощь / руководства приветствуются.

1 Ответ

0 голосов
/ 10 января 2019

Mockito 2 имеет механизм «opt-in» для включения моделирования конечных методов или классов, см. здесь . Вы включаете его с помощью механизма расширения mockito, создавая файл src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker, содержащий одну строку:

mock-maker-inline

(хорошо, этот файл должен быть в пути к классам).

Если это работает для вас, отлично. Если нет, то, вероятно, вы ничего не можете сделать.

Видите ли, инструменты сводятся к: манипулированию байтовым кодом. Как правило, не получается использовать более одного фреймворка.

Значение: для того, чтобы включить этот вид насмешки, необходимо манипулировать байт-кодом. И по очевидным причинам очень сложно сосуществовать с двумя различными структурами манипулирования байт-кодом.

Короче говоря: попробуйте этот механизм расширения, когда он не работает, вы должны отступить назад и спросить себя: какой именно конечной цели я намерен достичь?!

Скорее всего, вам, вероятно, не стоит тратить свое время на попытки насмехаться над вещами, работающими в ART.

...