我正在尝试使用jMockit来存根调用netscape.javascript.JSObject,遗憾的是这是一个带有一些本地方法的抽象类,这两个方法都不适合jMockit。有没有办法让我用jMockit或者使用普通的java来解决这个问题(如果可能的话我不想引入新的库)?我试图注入模拟的代码看起来如下(不要问):
JSObject win = JSObject.getWindow(this);
String someVal =(String)win.call(“foo”,new String [] {“”});
不幸的是我无法修改有问题的代码(再一次,请不要问),所以我可以对它进行任何类型的单元测试的唯一方法是,如果我能弄清楚如何删除或以其他方式消除对JSObject的调用。我当前的模拟实现为 getWindow 的调用返回了一个新的实例,并为调用的调用返回一个常量字符串,但当然它在运行时失败抱怨< / p>
类重新定义失败:尝试更改方法修饰符
从我的研究中我发现它意味着它试图模仿本地方法。
编辑:由于目标平台,我需要使用JDK 1.5来构建/测试,因此任何解决方案都必须在1.5上可行。
答案 0 :(得分:3)
您使用的是哪个版本的JMockit?根据{{3}},您应该能够毫无问题地模拟本机方法。
@Test
public void mockNativeMethod() {
new MockUp<Runtime>() {
@Mock
@SuppressWarnings("unused")
int availableProcessors() {
return 999;
}
};
assertEquals(999, Runtime.getRuntime().availableProcessors());
}
编辑:正如您所指出的,这不适用于Java 1.5。我担心唯一的解决方案是使用装饰器包装您的本机对象,该装饰器只是作为传递操作。这有点令人头疼,但它会允许嘲笑/拦截等。
答案 1 :(得分:1)
正如Brian指出的那样,JMockit支持模仿本机方法。 (Expectations API,如下面的测试所示,也支持它。)
@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());
}
问题是,JDK 1.5中的JVMTI实现不是很成熟,不支持重新定义native
方法。
我知道您需要在JDK 1.5环境中部署生产代码,但这不应该妨碍在开发环境中使用JDK 1.6。通常,在JDK 1.6上运行测试应该是非常安全和容易的,甚至可以使用JDK 1.6编译器编译所有源代码。您只需将javac“target”指定为“1.5”即可。在Eclipse中,“Project Properties - &gt; Java Compiler”下有一个“JDK Compliance”配置。