Java 如何使用jMockit模拟本机方法
我试图使用jMockit终止对netscape.javascript.JSObject的调用,不幸的是,这是一个抽象类,其中包含一些本机方法,这两种方法都不能很好地使用jMockit。对于我来说,有没有什么办法可以用jMockit或普通java(如果可能的话,我宁愿不引入新的库)来消除这个问题?我试图注入模拟的代码如下所示(不问): JSObject win=JSObject.getWindow(此)Java 如何使用jMockit模拟本机方法,java,jmockit,Java,Jmockit,我试图使用jMockit终止对netscape.javascript.JSObject的调用,不幸的是,这是一个抽象类,其中包含一些本机方法,这两种方法都不能很好地使用jMockit。对于我来说,有没有什么办法可以用jMockit或普通java(如果可能的话,我宁愿不引入新的库)来消除这个问题?我试图注入模拟的代码如下所示(不问): JSObject win=JSObject.getWindow(此) 字符串someVal=(String)win.call(“foo”,新字符串[]{”“}) 不
字符串someVal=(String)win.call(“foo”,新字符串[]{”“}) 不幸的是,我不能修改有问题的代码(再一次,不要问),所以我可以对它进行任何类型的单元测试的唯一方法是,如果我能够找出如何取消或以其他方式消除对JSObject的调用。我当前的mock实现为getWindow调用返回一个新的自身实例,并为call调用返回一个常量字符串,但在运行时它当然会失败 类重新定义失败:尝试更改方法修饰符 从我的研究中,我发现这意味着它试图模仿本地方法
编辑:由于目标平台,我需要使用JDK 1.5来构建/测试,因此任何解决方案都必须在1.5上可行。您使用的是哪个版本的JMockit?根据,您应该能够毫无问题地模拟本机方法
@Test
public void mockNativeMethod() {
new MockUp<Runtime>() {
@Mock
@SuppressWarnings("unused")
int availableProcessors() {
return 999;
}
};
assertEquals(999, Runtime.getRuntime().availableProcessors());
}
@测试
public void mockNativeMethod(){
新模型(){
@嘲弄
@抑制警告(“未使用”)
int可用处理器(){
返回999;
}
};
assertEquals(999,Runtime.getRuntime().availableProcessors());
}
编辑:正如您所指出的,这不适用于Java1.5。我担心唯一的解决方案是用一个装饰器包装您的原生对象,它只是作为一个传递。这有点令人头痛,但它允许模拟/拦截等。正如Brian指出的,JMockit支持模拟本地方法。 (下面的测试中显示的Expectations API也支持它。) 然而,问题是JDK1.5中的JVMTI实现还不是很成熟,不支持重新定义
本机方法
我知道您需要在JDK1.5环境中部署生产代码,但这不会妨碍您在开发环境中使用JDK1.6。通常,在JDK1.6上运行测试,甚至使用JDK1.6编译器编译所有源代码都应该是非常安全和容易的。您只需将javac“target”指定为“1.5”。在Eclipse中,“Project Properties->Java Compiler”下有一个“JDK Compliance”配置。我使用的是最新版本,但问题是我不得不使用JDK 1.5,它没有提供接口来允许插入模拟它们所需的本机方法。
@Test // this only works under JDK 1.6+; JDK 1.5 does not support redefining natives
public void mockNativeMethod()
{
new Expectations()
{
final System system = null;
{
System.nanoTime(); returns(0L);
}
};
assertEquals(0, System.nanoTime());
}