Junit测试用例不能按预期工作

sta*_*ion 2 java junit

我有以下jUnit测试用例来测试取幂

@Test
public void testExponentiation() {
    AssertSame("Not valid!",32.0,this.myObject.expo(2,5))
}
Run Code Online (Sandbox Code Playgroud)

我的世博会功能是

public double expo(int n1,int n2) {
    return Math.pow(n1,n2);
}
Run Code Online (Sandbox Code Playgroud)

这不能按预期工作,但AssertSame适用于Integer原始类型.可以解释为什么?

buc*_*buc 6

您的代码中有两个错误:

首先,assertSame()只能用于确定两个参数是否引用同一个对象(例如,引用是否相同,就像使用运算符一样==),并且它仅适用于引用类型(请参阅Javadoc).在您的情况下,指数方法返回值type(double),并且传递给assertSame()方法的预期结果也是值类型(float).

当Java在任何需要引用类型的位置找到值类型时,它会执行自动装箱(您可以在此处阅读),从而创建与值类型匹配的引用类型的新实例(例如Floatfor float).在你的情况下,这是基本上在后台发生的事情:

assertSame("Not valid!", new Double(32.0), new Double(this.myObject.expo(2,5)))
Run Code Online (Sandbox Code Playgroud)

或者更确切地说:

assertSame("Not valid!", Double.valueOf(32.0), Double.valueOf(this.myObject.expo(2,5)))
Run Code Online (Sandbox Code Playgroud)

由此可以清楚地看到,这两个引用永远不会相同,因为它们是两个不同的对象.要比较值,您必须使用其中一种assertEquals()方法.

第二个错误是其他答案说,由于浮点数的精度有限,你必须将它们与一些容差(或delta)进行比较.幸运的是,您不必为每次浮点比较手动执行此操作,因为JUnit assertEquals()为此提供了完美的方法(这里是Javadoc):

public static void assertEquals(java.lang.String message,
                                float expected,
                                float actual,
                                float delta)
Run Code Online (Sandbox Code Playgroud)

它期望预期值,实际值和它应该用于比较预期值和实际值的容差.如果您使用此方法,您的代码将如下所示:

@Test
public void testExponentiation() {
    assertEquals("Not valid!", 32.0, this.myObject.expo(2,5), 1e-5);
}
Run Code Online (Sandbox Code Playgroud)

希望它能成功运行并通过测试.

编辑:为什么assertSame()为整数操作的原因是Java缓存从-128到127的整数以节省内存.这意味着调用Integer.valueOf(5)将始终返回相同的Integer实例,因此它们的引用将是相等的.试试这个小例子:

Integer i1 = 6;                   // Autoboxing, Integer.valueof(6)
Integer i2 = Integer.valueOf(6);
Integer i3 = new Integer(6);

i1 == i2;      // True, their references are the same
i2 == i3;      // False
i1 == i3;      // False
Run Code Online (Sandbox Code Playgroud)