为什么我不能使用JMockit模拟数学 [英] Why can't I mock Math using JMockit
问题描述
使用JMockit(1.21)模拟出java.lang.Math
时遇到问题.请参阅以下内容,以简化我的实际课程.基本上在我的代码中的某个地方,我使用Math.pow(...)
并希望对其进行模拟.
I am running into a problem mocking out java.lang.Math
using JMockit (1.21). See below for a simplified use of my actual class. Basically somewhere in my code I use Math.pow(...)
and I whish to mock it.
public final class Calculator {
public final double power(double base, double exponent) {
return Math.pow(base, exponent);
}
}
对于我的测试代码,此测试有效.
As for my test code, this test works.
@Test
public void simpleTestWithoutMock() {
Calculator calculator = new Calculator();
double result = calculator.power(2, 3);
assertThat(result).isEqualTo(8);
}
此测试失败.
@Test
public void simpleTestWithMock(@Mocked Math math) {
new Expectations() {{ // This would be line 67 in below stracktrace
Math.pow(2,3); result = 1;
}};
Calculator calculator = new Calculator();
double result = calculator.power(2, 3);
assertThat(result).isEqualTo(1);
}
我收到的错误消息:
java.lang.NoClassDefFoundError: nl/endran/sandbox/CalculatorTest$1
at nl.endran.sandbox.CalculatorTest.simpleTestWithMock(CalculatorTest.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.ClassNotFoundException: nl.endran.sandbox.CalculatorTest$1
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 9 more
我能够像这样模拟其他系统类,例如System
和RunTime
,但是Math
似乎不起作用(String
也不行).我知道如何规避这是我的测试,因此我没有受到任何阻碍,但我无法理解为什么不能嘲笑Math
.删除Expectations块将不再导致NoClassDefFoundError
错误.我怀疑具有public static native
这样的签名的方法在其中起作用,但是我找不到任何东西.
I am able to mock other system classes like System
and RunTime
like this, but Math
just doesn't seem to work (nor does String
for that matter). I know how to circumvent this is my tests, so I am not blocked or anything, but I cannot understand why Math
cannot be mocked. Removing the Expectations block will not cause the NoClassDefFoundError
error anymore. I suspect methods that have a signature like public static native
to play a role in this, but I cannot find anything.
推荐答案
因为1)java.lang.Math
(尤其是Math.min(a, b)
)中的方法始终被其他类从java.lang.String
中查看)和2),当JMockit模拟一个类(无论如何使用@Mocked
)时,在测试期间都会对其进行模拟,而与 where 无关.来电来了.
Because 1) methods from java.lang.Math
(in particular, Math.min(a, b)
) get called all the time by other classes from the JRE (for example, look inside java.lang.String
), and 2) when JMockit mocks a class (with @Mocked
, anyway), it gets mocked for the duration of the test, regardless of where the calls are coming from.
最重要的是,除非您真的知道自己在做什么,否则请不要嘲笑低级JRE类.在这种特殊情况下,JMockit可能会拒绝java.lang.Math
的完整模拟,因为确实没有充分的理由(我可以看到).
Bottom line, don't mock low-level JRE classes unless you really know what you are doing. In this particular case, JMockit should probably deny the full mocking of java.lang.Math
, as really there is no good reason (that I can see) for doing it.
这篇关于为什么我不能使用JMockit模拟数学的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!