2012-06-28 22 views
9

que había una prueba JUnit valer dos objetos dobles con lo siguiente:diferencia Junit entre assertEquals (Doble, Doble) y assertEquals (doble, doble, delta)

Assert.assertEquals(Double expected, Double result); 

Ésta era estaba bien entonces decidió cambiar usar el doble primitivo que resultó ser obsoleto a menos que también proporcione un delta.

así que lo que me pregunto es ¿cuál es la diferencia entre usar el objeto Doble o el tipo primitivo en este assertEquals? ¿Por qué está obsoleto el uso de objetos sin un delta ok pero luego el uso de las primitivas sin un delta? ¿Java está haciendo algo en segundo plano que ya tiene en cuenta un valor delta predeterminado?

Gracias.

Respuesta

12

No hay assert method in JUnit con la firma

assertEquals(Double expected, Double result); 

Hay uno, sin embargo, genérico de objetos:

assertEquals(Object expected, Object result); 

Para esto se necesitan equals método de los objetos y como se puede esperar, es no se recomienda usar esto para comparar objetos Double.

Para los dobles, como observó, es absolutamente necesario usar un delta para comparar, para evitar problemas con el redondeo de coma flotante (como ya se explicó en algunas otras respuestas). Si se utiliza la versión 3-argumento de assertEquals con double argumentos

assertEquals(double expected, double actual, double delta); 

sus Double s obtendrán en silencio sin embalaje a double y todo funciona bien (y sus pruebas no van a fallar inesperadamente :-).

+1

+1 re unboxing, sí, con la advertencia de que tendrá un comportamiento ligeramente diferente si uno u otro Double es nulo. Con el Objeto, obtendrás un buen mensaje, con el delta, obtendrás una NullPointerException. –

+1

Mi experiencia es que estos métodos no funcionan bien para números muy grandes en algunas circunstancias, particularmente si sus datos varían en órdenes de magnitud. Dos números pueden tener un porcentaje de error muy pequeño, pero requieren un delta aparentemente grande para coincidir. Pero ese mismo delta no funcionaría para valores mucho más pequeños en sus datos. En algunos casos, incluso se puede esperar que números muy grandes coincidan con casi todos los dígitos significativos. En otros casos, como cuando se comparan dos algoritmos de FFT optimizados, es mucho menos probable. Un método más robusto es restringir el error relativo. – orodbhen

+0

@orodbhen Para que funcione, se debe calcular la delta basándose en el exponente del valor esperado, por lo que si 'double e' es el valor esperado, entonces delta debe ser' double d = Math.pow (10, Math.log10 (Math. abs (e)) - 12); 'donde' 12' es el número práctico máximo de dígitos significativos. Si multiplicas el log10 por el valor <1.0, entonces la prueba fallará para que 'e' tenga un exponente positivo grande y, por el contrario, si multiplicas log10 por valor> 1.0, fallará para que 'e' tenga un gran exponente negativo - y este es el efecto sobre el que estabas escribiendo. Por lo tanto, asegúrese de que el delta esté bien ajustado al exponente del valor esperado. – Cromax

0

SOURCE. Afirma que dos dobles o flotantes son iguales dentro de un delta positivo. Si no lo son, se lanza un AssertionError. Si el valor esperado es infinito, se ignora el valor delta. Los NNA se consideran iguales.

0

Yo diría que la comparación de dobles, primitivos u objetos, es inútil sin un delta. Saber cómo funcionan los números de punto de flujo es clave para hacer un trabajo numérico.

El objeto puede estar utilizando .equals debajo de las cubiertas; el primitivo no tiene opción además de ==.

El hecho de que la versión del objeto no esté usando un delta no lo hace una mejor idea.

5

Doble matemática raramente si alguna vez da exactamente resultados iguales. Por ejemplo, 0.1 * 0.1 != 0.01. Por lo general, necesita al menos algún delta al comparar resultados de doble precisión.

Por otro lado, si está comparando Double s en caja, se supone que desea la igualdad exacta. Java no tiene en cuenta un valor delta predeterminado, pero Double.equals tiene un comportamiento ligeramente diferente de ==: en particular, its handling of NaNs.

Esto tiene sentido en las pruebas, porque Double.NaN != Double.NaN, pero en una prueba, si esperaba un NaN y NaN se devolvió, esa es una respuesta correcta.

0

mejor escribir algo como esto:

assertEquals(23.0, 250.0, 0.0) 

0,0 - es delta. Lea por qué sus métodos están en desuso.