【问题标题】:Is there a way to test JNI method without writing Java wrapper?有没有办法在不编写 Java 包装器的情况下测试 JNI 方法?
【发布时间】:2017-06-29 15:05:24
【问题描述】:

我知道我们可以编写一些 Java 原生方法来测试 JNI 的 C/C++ 代码,但是这需要太多时间,而且大部分 C/C++ 代码不需要从 Java 中访问,有没有办法测试以编程方式?

【问题讨论】:

  • 如果要测试不能从 Java 访问的 C/C++ 代码,可以使用 C/C++ 单元测试框架。
  • 嗯,JVM 本身是用 C 编写的,不是吗?但是像测试 Java 代码一样测试 JNI 代码要容易得多。为什么要这样测试你的 JNI 代码?
  • @AndrewHenle 一些 C 代码不必从 Java 访问。例如编解码器工具。
  • @AndyThomas 谢谢,我对 C/C++ 测试框架一点也不熟悉,有没有办法在 Android Studio 中做到这一点?
  • @MrROY - 这是一个现有问题 - stackoverflow.com/questions/18126967/….

标签: java android-ndk java-native-interface


【解决方案1】:

你的问题有两个方面。

如果您想对通常在 Java Android 应用程序上下文中使用的底层 C/C++ 代码进行单元测试,您可以使用googletestgoogletest 随 Android NDK (third_party/googletest) 一起提供,用于测试 NDK 本身。 Here 您可以找到运行此类单元测试的分步说明。

此 C 代码通常是跨平台的,因此也可以为构建机器编译它并在 本机 进行测试 - 无需 Android 设备或模拟器。

但是这种方法无法测试实际使用 JNI 函数的 C 代码(例如,负责从 Java 对象或数据类型转换为 C/C++ 并返回的 C 代码)。虽然最佳实践是保持这种 wrapper 精简和简单,但现实经常迫使我们将一些非平凡的逻辑放入这些函数中。即使它很简单,它也应该是可测试的。

unittest一个本地方法,你必须a)模拟底层C++层,b)模拟调用这个本地的Java类方法,并且 c) 模拟从本机代码调用的任何 Java 方法。然后,您可以使用 JUnit 在设备或模拟器上运行测试。您的代码应该以允许这种解构的方式设计。特别是,您需要遵守 JNI 回调仅位于包装类中的规则,而核心中不使用 Java 相关的代码。

实际上,如果设计足够简洁并且角色分离足够严格,您可以在主机上运行这些 Java 测试,而不是使用 Android 设备或模拟器。您的 C++ 代码应该能够在没有 NDK 扩展的情况下使用主机工具链构建(例如__android_log_print()),也可以在没有 Android 环境的情况下运行(例如,您可以FindClass("java/util/ArrayList"),但不能FindClass("android/util/SparseArray"))。

不幸的是,Android Studio 似乎无法提供帮助,但我们使用单独的原生 cmake 来使用宿主 C 编译器构建单元测试。当然,这样的测试不能替代设备端测试,但它们在 CI 环境中是非常宝贵的。

更新

如果您对此主题感兴趣,请务必阅读Android JUnit Testing for Native Libraries by Suresh Joshi

【讨论】:

  • "实际上,如果设计足够简洁,角色分离足够严格,您可以在主机上运行这些 Java 测试,而不是使用 Android 设备或模拟器。" - 你这是什么意思?角色分离与您可以在哪里测试代码有什么关系?这是一个巨大的痛苦,但您可以在主机上运行 JUnit 测试,但针对主机兼容的二进制文件(所以 - 与测试 NDK 编译的库不完全相同,但很接近)。这让您可以测试任何可从 Java 访问的内容。
  • @SJoshi 你需要干净的设计来处理这个问题,因为你的 C++ 代码应该能够在没有 NDK 扩展(例如__android_log_print)的情况下使用主机工具链构建,并且也可以在没有 Android 环境的情况下运行(例如你可以FindClass("java/util/ArrayList"),但不能FindClass("android/util/SparseArray"))。
  • 啊,好吧,我明白了 - 我会假设如果有本地(非 Android)单元测试,那么没有 NDK 扩展是给定的,因为没有 NDK 就无法编译.但是,话又说回来 - 最好永远不要假设:)
  • @SJoshi 开头为stackoverflow.com/a/47325408/192373!我希望 Google 能够拿起手套,为 Android 特定的符号和类提供一个框架。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 2017-01-10
相关资源
最近更新 更多