如何在 C/C++ 中创建 JNIEnv 模拟

Posted

技术标签:

【中文标题】如何在 C/C++ 中创建 JNIEnv 模拟【英文标题】:How to create a JNIEnv mock in C/C++ 【发布时间】:2008-10-14 13:27:02 【问题描述】:

我正在用 C 语言编写一些希望使用 cunit 进行测试的 JNI 代码。为了调用 JNI 函数,我需要创建一个有效的 JNIEnv 结构。

有谁知道是否有用于此目的的模拟框架,或者谁能给我一些关于如何自己创建模拟 JNIEnv 结构的指示?

【问题讨论】:

请查看我的答案的编辑版本,其中包括一个带有模拟 JNI 函数实现的完整 C++ 程序。 【参考方案1】:

jni.h 包含 JNIEnv_ 的完整结构,包括“跳转表”JNINativeInterface_。您可以创建自己的 JNINativeInterface_(指向模拟实现)并从中实例化 JNIEnv_。

针对 cme​​ts 进行编辑:(我没有查看您引用的其他 SO 问题)

#include "jni.h"
#include <iostream>

jint JNICALL MockGetVersion(JNIEnv *)

  return 23;


JNINativeInterface_ jnini = 
  0, 0, 0, 0, //4 reserved pointers
  MockGetVersion
;

// class Foo  public static native void bar(); 
void Java_Foo_bar(JNIEnv* jni, jclass)

  std::cout << jni->GetVersion() << std::endl;


int main()

  JNIEnv_ myjni = &jnini;
  Java_Foo_bar(&myjni, 0);
  return 0;

【讨论】:

是的,这就是我认为我需要做的。不过,为了让生活更有趣,Sun 无奈地将 JNIEnv 结构体设为常量,因此它覆盖其中的函数指针成为一项非常重要的任务。 如果您有兴趣,***.com/questions/203058/… 绘制了强制指针更改到此 const 结构的问题之一的解决方案【参考方案2】:

嘲笑 JNI 对我来说听起来像是一个痛苦的世界。我认为你可能会更好地模拟用 Java 实现的调用,并使用 Junit 来测试 Java 端的功能

【讨论】:

我对您的建议的问题是,通过 Java 测试代码不是单元测试,因为它们通过 JNI。如果失败,可能是由于 Java 代码、C/Java 数据类型匹配、C coce、JNI 中的错误等。继续... ...所以如果我要正确地对 JNI C 代码进行单元测试,我必须模拟 JNI 并从 C 代码中调用 C 函数。 你可能是对的,我有一段时间没有做过 jni,但对我来说,模拟起来似乎很棘手的是 C/Java 数据类型匹配。我个人会考虑包装 C/Java 接口,然后模拟它。【参考方案3】:

引用:“jnimock 是在 gmock 之上实现的。它提供了两个 C++ 类 'JNIEnvMock' 和 'JavaVMMock' 来分别模拟 'JNIEnv' 和 'JavaVM'。”

https://github.com/ifokthenok/jnimock

【讨论】:

以上是关于如何在 C/C++ 中创建 JNIEnv 模拟的主要内容,如果未能解决你的问题,请参考以下文章

如何模拟在函数中创建的类(新运算符)?

如何在浮点数数组中创建一个由 1 组成的圆圈

如何在 Java 中创建静态局部变量?

如何使用mockito在安卓系统中创建模拟api响应[关闭]。

如何在 .NET 中创建虚拟网络适配器?

从 C++ 访问在 python 中创建的 C++ 类