我有一個函式,我想在其中替換某些組件部分(余弦、正弦、...)的行為,我正在嘗試為這些部分創建一個模擬并將它們傳遞給函式。
class Function1Test {
private static final double accuracy = 10e-5;
static Function1 firstFunction;
static Function2 secondFunction;
static TrFunc.MyCos cos;
static TrFunc.MySin sin;
static TrFunc.MyTan tan;
static TrFunc.MySec sec;
static LgFunc.Log2 log2;
static LgFunc.Log3 log3;
static LgFunc.Log5 log5;
static LgFunc.Log10 log10;
static Func_System sys;
@BeforeAll
static void setUp() {
cos = mock(TrFunc.MyCos.class);
sin = mock(TrFunc.MySin.class);
tan = mock(TrFunc.MyTan.class);
sec = mock(TrFunc.MySec.class);
firstFunction = new Function1(cos, sin, tan, sec);
log2 = mock(LgFunc.Log2.class);
log3 = mock(LgFunc.Log3.class);
log5 = mock(LgFunc.Log5.class);
log10 = mock(LgFunc.Log10.class);
secondFunction = new Function2(log2, log3, log5, log10);
sys = new Func_System(firstFunction, secondFunction);
}
static Stream<Arguments> valuesRangeProvider(){
return Stream.of(
arguments(-6.282185307179586, 1001001.3330000667),
arguments(-0.161592653589793, 33.496935752492160)
);
}
@DisplayName("Integration Test with Mocks")
@ParameterizedTest(name = "{index}: Check range of values, x = {0}")
@MethodSource("valuesRangeProvider")
void test_0(double value, double expected) throws Exception {
when(firstFunction.sin.mySin(value, accuracy)).thenReturn(sin(value));
when(firstFunction.cos.myCos(value, accuracy)).thenReturn(cos(value));
when(firstFunction.tang.myTan(value, accuracy)).thenReturn(sin(value)/cos(value));
when(firstFunction.sec.mySec(value, accuracy)).thenReturn(1/cos(value));
assertEquals(expected, firstFunction.calculate(value, accuracy), accuracy);
}
問題是,我收到以下訊息:
*org.mockito.exceptions.misusing.MissingMethodInvocationException: when() 需要一個引數,該引數必須是“模擬方法呼叫”。例如:when(mock.getArticles()).thenReturn(articles); 此外,可能會出現此錯誤,因為:
- 你存根其中之一:final/private/equals()/hashCode() 方法。這些方法不能被存根/驗證。不支持在非公共父類上宣告的模擬方法。
- 在 when() 中,您不會在模擬上呼叫方法,而是在其他物件上呼叫方法。*
這些方法都不是私有的或最終的
public class TrFunc {
public static class MyCos {
public static double myCos(double x, double accuracy) throws Exception {
if (accuracy < 0){
throw new Exception("The accuracy below zero");
}
double theta_norm = Math.abs(x);
theta_norm -= Math.floor(theta_norm/Math.PI/2)*2*Math.PI;
double result = 1;
double step = 1;
int i;
for (i = 1; step > accuracy && i != Integer.MAX_VALUE; i ){
step = step*theta_norm*theta_norm/(2*i-1)/(2*i);
if (i % 2 == 1){
result -= step;
} else {
result = step;
}
}
if (!Double.isFinite(result) || i == Integer.MAX_VALUE-1){
throw new Exception("Too many iterations");
}
return result;
}
private static double factorial(int numer) {
double factorial = 1.0d;
while (numer != 0) {
factorial *= numer--;
}
return factorial;
}
}
public static class MySin {
public static double mySin(double x, double accuracy) throws Exception {
return MyCos.myCos(Math.PI/2 - x, accuracy);
}
}
public static class MyTan {
public static double myTan(double x, double accuracy) throws Exception {
double divisor = MyCos.myCos(x, accuracy);
if (Math.abs(divisor) <= accuracy) throw new Exception("Division by zero");
return MySin.mySin(x, accuracy) / divisor;
}
}
public static class MySec {
public static double mySec(double x, double accuracy) throws Exception {
double divisor = MyCos.myCos(x, accuracy);
if (Math.abs(divisor) <= accuracy) throw new Exception("Division by zero");
if ((x Math.PI / 2) / Math.PI % 1 == 0) throw new Exception("x can't be Pi*n-Pi/2");
return 1 / divisor;
}
}
}
uj5u.com熱心網友回復:
在這種情況下,您試圖在實用程式類上模擬靜態方法,而 Mockito 不允許這樣做。有關更多詳細資訊,請參閱使用 Mockito 模擬靜態方法。
如果您在這里嘗試測驗的是數學的有效性,您可以簡單地使用基本斷言對它們進行單元測驗。如果您想在測驗中使用模擬,您可以探索上述帖子中建議的替代方案,或者重組您的代碼以依賴非靜態方法。
假設 Function1 只是傳遞給它的變數的持有者,對于您要更改的每個內部類:
public static class MySin {
public static double mySin(double x, double accuracy) throws Exception {
return MyCos.myCos(Math.PI/2 - x, accuracy);
}
}
到
public static class MySin {
public double mySin(double x, double accuracy) throws Exception {
return MyCos.myCos(Math.PI/2 - x, accuracy);
}
}
注意方法上洗掉的靜態修飾符。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/455836.html
上一篇:使用“@”匯入進行笑話測驗
