Skip to content

Replace mockito-android mock maker with dexmaker-mockito-inline fork#3789

Closed
jselbo wants to merge 2 commits intomockito:mainfrom
jselbo:android-v2
Closed

Replace mockito-android mock maker with dexmaker-mockito-inline fork#3789
jselbo wants to merge 2 commits intomockito:mainfrom
jselbo:android-v2

Conversation

@jselbo
Copy link
Copy Markdown
Collaborator

@jselbo jselbo commented Feb 26, 2026

Fork dexmaker-mockito-inline (https://github.com/linkedin/dexmaker/tree/main/dexmaker-mockito-inline) to replace the subclass-based mock maker with a JVMTI-based inline mock maker that supports mocking final classes and methods on Android.

This allows Mockito to be useful in a modern Kotlin Android ecosystem where classes are final by default unless explicitly marked with the open keyword. The subclass mock maker cannot mock final classes, and the inline mock maker does not work on Android.

Users currently work around this limitation by:

Risks/Considerations:

  • Backwards compatibility
    • I think changing mockito-android distribution from jar to aar will be transparent for Gradle users, but not sure about other build systems.
    • Now requires min API 28 (Android P) - the instrumentation test build will fail if the test's manifest specifies a lower min SDK. According to the Android Studio version distribution dialog, Android P+ covers 95% of Android users. We may have Mockito users running tests on pre-API 28 emulators, but we can encourage them to stay on an older version of mockito-android or upgrade the tests to run on a newer API.
  • Forking
    • Instead of forking, we could probably simply depend on the dexmaker-mockito-inline artifact. The downside of this seems to be lack of control and limiting future improvements.
  • Licensing
    • external/:
      • jdk/jvmti.h is from Oracle OpenJDK under GPL-2.0
      • slicer/ is from AOSP under Apache 2.0
    • agent.cc and all new Java sources except InlineAndroidMockMaker.java are copied from dexmaker-mockito-inline licensed under Apache 2.0. Confusingly, the headers of these sources state "Copyright (C) 2017 The Android Open Source Project" even though they seem to originate from the dexmaker repo itself. I opened License headers? linkedin/dexmaker#208 asking about this. I retained the headers as-is.
  • Dispatcher
    • dexmaker-mockito-inline includes a pre-built dispatcher.jar with dex bytecode to allow instrumenting methods with JVMTI. I followed the pattern of MockK and build the dispatcher from source instead of having a prebuilt.

Technical changes:

  • Convert mockito-android from Java library (JAR) to Android library (AAR) to allow packaging native code
  • Add native NDK/CMake code (JVMTI agent + AOSP slicer library)
  • Fork dexmaker Java sources under org.mockito.android.internal.creation.inline
  • Add InlineAndroidMockMaker entry-point delegating to InlineDexmakerMockMaker
  • Build dispatcher.jar via new mockito-android-dispatcher submodule
  • Require min SDK 28 (Android P) via manifest for JVMTI support
  • Conditionally include mockito-android in the Gradle project based on Android SDK availability
  • Add integration tests for final class mocking

Note for reviewers: the only "new" code is InlineAndroidMockMaker.java. Everything else is a copy/fork.

Fixes #3788

Checklist

  • Avoid other runtime dependencies

This adds a new compile dependency for mockito-android on com.linkedin.dexmaker:dexmaker which allows runtime generation of Android dex byte code, similar to Byte-Buddy on the JVM.

…line

Fork dexmaker-mockito-inline (v2.28.4) to replace the ByteBuddy subclass-based
mock maker with a JVMTI-based inline mock maker that supports mocking final
classes and methods on Android.

Key changes:
- Convert mockito-android from Java library (JAR) to Android library (AAR)
- Add native NDK/CMake code (JVMTI agent + AOSP slicer library)
- Fork dexmaker Java sources under org.mockito.android.internal.creation.inline
- Update JNI function names in agent.cc to match new package
- Add InlineAndroidMockMaker entry-point delegating to InlineDexmakerMockMaker
- Build dispatcher.jar from source via mockito-android-dispatcher submodule
- Require min SDK 28 (Android P) for JVMTI support
- Conditionally include mockito-android based on Android SDK availability
- Add integration tests for final class mocking

Fixes mockito#3788
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Feb 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.90%. Comparing base (25f1395) to head (9ae174f).

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #3789      +/-   ##
============================================
+ Coverage     86.50%   86.90%   +0.40%     
+ Complexity     3004     2997       -7     
============================================
  Files           343      340       -3     
  Lines          9099     9021      -78     
  Branches       1121     1105      -16     
============================================
- Hits           7871     7840      -31     
+ Misses          945      905      -40     
+ Partials        283      276       -7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jselbo jselbo marked this pull request as ready for review February 26, 2026 23:23
@raphw
Copy link
Copy Markdown
Member

raphw commented Mar 2, 2026

I do not know enough on the background to decide if forking or linking is the better solution, but I wonder: Instead of forking, we could probably simply depend on the dexmaker-mockito-inline artifact. The downside of this seems to be lack of control and limiting future improvements.

If the limitation is in the future and if no API is exposed, could we go for linking until we need to potentially fork?

@jselbo
Copy link
Copy Markdown
Collaborator Author

jselbo commented Mar 3, 2026

Thinking about it more, I think linking for now makes sense for simplicity. I will open a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: integrate dexmaker-mockito-inline for modern Android support

3 participants