我有以下用于测试指数的jUnit测试用例
@Test
public void testExponentiation() {
AssertSame("Not valid!",32.0,this.myObject.expo(2,5))
}
我的世博会功能是
public double expo(int n1,int n2) {
return Math.pow(n1,n2);
}
这不能按预期工作,但AssertSame
适用于整数原始类型。有人可以解释原因吗?
答案 0 :(得分:6)
您的代码中有两个错误:
首先,assertSame()
只能用于确定两个参数是否引用同一个对象(例如,引用是相同的,就像使用运算符{{1}一样}),它仅适用于引用类型(see the Javadoc)。在您的情况下,指数方法返回值类型(==
),并且传递给double
方法的预期结果也是值类型(assertSame()
)。
当Java在任何需要引用类型的位置找到值类型时,它会执行 autoboxing (you can read about it here),从而创建一个与值类型匹配的引用类型的新实例(对于float
的示例Float
。在你的情况下,这是基本上在后台发生的事情:
float
或更确切地说:
assertSame("Not valid!", new Double(32.0), new Double(this.myObject.expo(2,5)))
由此可以清楚地看到,这两个引用永远不会相同,因为它们是两个不同的对象。要比较值,您必须使用assertSame("Not valid!", Double.valueOf(32.0), Double.valueOf(this.myObject.expo(2,5)))
方法之一。
第二个错误是其他答案说,由于浮点数的精度有限,你必须将它们与一些容差(或delta)进行比较。幸运的是,您不必为每次浮点比较手动执行此操作,因为JUnit为此提供了完美的assertEquals()
方法(here's the Javadoc):
assertEquals()
它期望它应该用于比较预期值和实际值的预期值,实际值和容差。如果您使用此方法,您的代码将如下所示:
public static void assertEquals(java.lang.String message,
float expected,
float actual,
float delta)
希望它能成功运行并通过测试。
编辑:@Test
public void testExponentiation() {
assertEquals("Not valid!", 32.0, this.myObject.expo(2,5), 1e-5);
}
为整数操作的原因是Java缓存-128到127之间的整数以节省内存。这意味着调用assertSame()
将始终返回相同的Integer.valueOf(5)
实例,因此它们的引用将是相同的。试试这个小例子:
Integer