【发布时间】:2021-08-27 07:47:16
【问题描述】:
我正在使用 PowerMockito 和 JUnit。如何模拟 JNI 函数?
Class A{
public native String test();
}
Class Util{
public static String test() {
A a = new A();
return a.test();
}
}
单元测试:
Class ATest{
@Test
public void test1() {
A a = PowerMockito.mock(A.class);
PowerMockito.when(a.test()).thenReturn("test");
boolean check = Util.test().equals("test")
assert check == true
}
}
如果我运行测试,我得到的测试是原生的。如何解决这个问题?
【问题讨论】:
-
你确定,你使用的是 Spock,代码看起来更像是带有 groovy 的 JUnit。
-
在 Spock 中,您可以像任何其他方法一样模拟本机方法。不需要 Mockito 或 PowerMock,您只需使用 Spock 模拟即可。您唯一需要使用 Mockito、PowerMock 或 Sarek 等附加模拟工具的就是模拟实用程序类的静态方法。不过,如果我是你,我会避免这种情况。只需重构实用程序类即可通过方法参数或带有 setter 方法的静态成员注入
A实例。然后你可以简单地注入一个普通的 mock 并且不用额外的花哨的工具来掩盖你糟糕的应用程序设计。去重构吧! -
此外,您以错误的方式使用 PowerMock:您正在创建一个模拟,但没有将其注入静态方法,与上述相同的问题。您还必须存根构造函数调用,确保构造函数返回您的模拟。所有这些都是错误的设计决策的结果,即在方法中创建依赖实例作为局部变量,使代码紧密而不是松散耦合,这也阻碍了可测试性。如果你坚持的话,你可以使用 PowerMock 来解决这个问题,但是不得不使用那个工具已经很糟糕了。
-
昨天忘记在这里发布我的发现了。 @kriegaex 是对的。我错过了嘲笑构造函数。这已经解决了这个问题。我使用了 mock,因为我必须验证方法调用。
-
那么请写一个全面的答案,展示解决您问题的代码,为大家谋福利。您向社区寻求帮助,现在您有机会向同一个社区返回一些东西。还请考虑重构您(几乎)不可测试的静态辅助方法。相信我,在您告别 PowerMock 之后,您作为开发人员的生活会好很多。
标签: unit-testing java-native-interface powermock powermockito