Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88ea9ba9 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Ravenwood: Add device test to RavenwoodMockitoTest

Test: atest RavenwoodMockitoTest RavenwoodMockitoTest_device
Bug: 310268946
Bug: 292141694
Change-Id: Iaf0f689d5513a1a4dce4d756aad2152202d72e6d
parent 2488dbee
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
# Ravenwood and Mockito

Last update: 2023-11-13

- As of 2023-11-13, `external/mockito` is based on version 2.x.
- Mockito didn't support static mocking before 3.4.0.
  See: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#48

- Latest Mockito is 5.*. According to https://github.com/mockito/mockito:
  `Mockito 3 does not introduce any breaking API changes, but now requires Java 8 over Java 6 for Mockito 2. Mockito 4 removes deprecated API. Mockito 5 switches the default mockmaker to mockito-inline, and now requires Java 11.`

- Mockito now supports Android natively.
  See: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.1
  - But it's unclear at this point to omakoto@ how the `mockito-android` module is built.

- Potential plan:
  - Ideal option:
    - If we can update `external/mockito`, that'd be great, but it may not work because
      Mockito has removed the deprecated APIs.
  - Second option:
    - Import the latest mockito as `external/mockito-new`, and require ravenwood
      to use this one.
    - The latest mockito needs be exposed to all of 1) device tests, 2) host tests, and 3) ravenwood tests.
    - This probably will require the latest `bytebuddy` and `objenesis`.
 No newline at end of file
+34 −0
Original line number Diff line number Diff line
@@ -36,3 +36,37 @@ android_ravenwood_test {
    ],
    auto_gen_config: true,
}

android_test {
    name: "RavenwoodMockitoTest_device",

    srcs: [
        "test/**/*.java",
    ],
    static_libs: [
        "junit",
        "truth",

        "androidx.test.rules",

        "ravenwood-junit",

        "mockito-target-extended-minus-junit4",
    ],
    libs: [
        "android.test.mock",
        "android.test.base",
        "android.test.runner",
    ],
    jni_libs: [
        // Required by mockito
        "libdexmakerjvmtiagent",
        "libstaticjvmtiagent",
    ],
    test_suites: [
        "device-tests",
    ],
    optimize: {
        enabled: false,
    },
}
+28 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.ravenwood.mockitotest">

    <application android:debuggable="true" >
        <uses-library android:name="android.test.runner" />
    </application>

    <instrumentation
        android:name="androidx.test.runner.AndroidJUnitRunner"
        android:targetPackage="com.android.ravenwood.mockitotest"
        />
</manifest>
+31 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<configuration description="Runs Frameworks Services Tests.">
    <option name="test-suite-tag" value="apct" />
    <option name="test-suite-tag" value="apct-instrumentation" />

    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
        <option name="cleanup-apks" value="true" />
        <option name="test-file-name" value="RavenwoodMockitoTest_device.apk" />
    </target_preparer>

    <option name="test-tag" value="FrameworksMockingServicesTests" />

    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
        <option name="package" value="com.android.ravenwood.mockitotest" />
        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
    </test>
</configuration>
+106 −0
Original line number Diff line number Diff line
@@ -22,10 +22,37 @@ import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.Intent;
import android.platform.test.annotations.IgnoreUnderRavenwood;
import android.platform.test.ravenwood.RavenwoodRule;

import org.junit.Rule;
import org.junit.Test;

public class MockitoTest {
public class RavenwoodMockitoTest {
    @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule();


// Use this to mock static methods, which isn't supported by mockito 2.
// Mockito supports static mocking since 3.4.0:
// See: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#48

//    private MockitoSession mMockingSession;
//
//    @Before
//    public void setUp() {
//        mMockingSession = mockitoSession()
//                .strictness(Strictness.LENIENT)
//                .mockStatic(RavenwoodMockitoTest.class)
//                .startMocking();
//    }
//
//    @After
//    public void tearDown() {
//        if (mMockingSession != null) {
//            mMockingSession.finishMocking();
//        }
//    }

    @Test
    public void testMockJdkClass() {
        Process object = mock(Process.class);
@@ -35,20 +62,32 @@ public class MockitoTest {
        assertThat(object.exitValue()).isEqualTo(42);
    }

    /* It still doesn't work...
    /*
 - Intent can't be mocked because of the dependency to `org.xmlpull.v1.XmlPullParser`.
   (The error says "Mockito can only mock non-private & non-final classes", but that's likely a
   red-herring.)

STACKTRACE:
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class android.content.Intent.

Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
  :

Underlying exception : java.lang.IllegalArgumentException: Could not create type
    at com.android.ravenwood.mockito.RavenwoodMockitoTest.testMockAndroidClass1
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

... But Intent public, non-final.
  :

Caused by: java.lang.ClassNotFoundException: org.xmlpull.v1.XmlPullParser
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 54 more
     */
    // @Test
    private void testMockAndroidClass1() {
    @Test
    @IgnoreUnderRavenwood
    public void testMockAndroidClass1() {
        Intent object = mock(Intent.class);

        when(object.getAction()).thenReturn("ACTION_RAVENWOOD");
Loading