Java JUnit: el método X es ambiguo para el tipo Y

98

Tenía algunas pruebas funcionando bien. Luego, lo moví a un paquete diferente y ahora recibo errores. Aquí está el código:

import static org.junit.Assert.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.jgrapht.Graphs;
import org.jgrapht.WeightedGraph;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleWeightedGraph;
import org.junit.*; 

@Test
    public void testEccentricity() {
        WeightedGraph<String, DefaultWeightedEdge> g = generateSimpleCaseGraph();
        Map<String, Double> eccen = JGraphtUtilities.eccentricities(g);

        assertEquals(70, eccen.get("alpha"));
        assertEquals(80, eccen.get("l"));
        assertEquals(130, eccen.get("l-0"));
        assertEquals(100, eccen.get("l-1"));
        assertEquals(90, eccen.get("r"));
        assertEquals(120, eccen.get("r-0"));
        assertEquals(130, eccen.get("r-1"));
    }

El mensaje de error es este:

El método assertEquals (Object, Object) es ambiguo para el tipo JGraphtUtilitiesTest

¿Cómo puedo arreglar esto? ¿Por qué ocurrió este problema cuando moví la clase a un paquete diferente?

Nick Heiner
fuente
cuéntanos cómo se declara tu clase. Me parece que has heredado de JUnit3 y luego has intentado importar estáticamente desde JUnit4.
bmargulies
sí, en realidad, tenía JUnit3 en el paquete A y usé JUnit4 en el paquete B, donde originalmente escribí estas pruebas. Luego cambié del Paquete B al Paquete A y surgió el problema. Pero no veo nada en esta clase que indique JUnit 3. ¿Dónde se declara?
Nick Heiner
@Rosarch ¿Están estas JGraphtUtilities disponibles en cualquier lugar? ¡No veo métodos para producir excentricidades en JGraphT!
Nick

Respuestas:

205

El método assertEquals (Object, Object) es ambiguo para el tipo ...

Lo que este error significa es que está pasando un doubley y Doubleen un método que tiene dos firmas diferentes: assertEquals(Object, Object)y assertEquals(double, double)ambas podrían llamarse, gracias al autoboxing.

Para evitar la ambigüedad, asegúrese de igualar assertEquals(Object, Object)(pasando dos dobles) o assertEquals(double, double)(pasando dos dobles).

Entonces, en su caso, debe usar:

assertEquals(Double.valueOf(70), eccen.get("alpha"));

O:

assertEquals(70.0d, eccen.get("alpha").doubleValue());
Pascal Thivent
fuente
ok, o podría simplemente cambiarlo para usar JUnit 4 en lugar de JUnit 3. ¿Cómo hago eso?
Nick Heiner
8
La solución no es realmente cambiar de una versión a otra. En cambio, ayude al compilador y elimine la ambigüedad como sugerí.
Pascal Thivent
1
De todos modos, ¿no debería ser assertEquals (70.0d, eccen.get ("alpha")); ?
mhaller
3
@mahller No estoy seguro de con quién está hablando, pero, incluso si es más correcto que el código del OP, sigue siendo ambiguo si la versión de JUnit tiene ambos assertEquals(Object, Object)y assertEquals(double, double)cuál es el caso de JUnit 4.4, 4.5. Pero como dije, cambiar la versión de JUnit no es la solución real, solo arregla el problema.
Pascal Thivent
1
@Rosarch Para este caso particular, no es un problema en JUnit 3.8.1, no es un problema en JUnit 4.3, es un problema en JUnit 4.4, es un problema en JUnit 4.5 (pero el método toma 2 doubles está en desuso), no es un problema en JUnit 4.6 (el método ha sido eliminado). Entonces, haga su elección, pero debe corregir el código.
Pascal Thivent
1

Puedes usar el método

assertEquals(double expected, double actual, double delta)

Lo cual tendrá en cuenta los errores de redondeo que son distintos al punto flotante (consulte esta publicación, por ejemplo). Puedes escribir

assertEquals(70, eccen.get("alpha"), 0.0001);

Esto significa que siempre que los dos valores difieran en menos de 0,0001, se considerarán iguales. Esto tiene dos ventajas:

  • Compara los valores de coma flotante como se supone que deben
  • No es necesario lanzar, ya que la afirmación de tres argumentos solo se aplica a dobles, no a Objetos genéricos
Paolo
fuente
0

La solución más simple a este problema es simplemente convertir el segundo parámetro en una primitiva:

assertEquals(70, (double)eccen.get("alpha"));

Se eliminó la ambigüedad.

Esto es válido para cualquiera de las subclases de Number, por ejemplo:

assertEquals(70, (int)new Integer(70));

También resolvería una ambigüedad.

Sin embargo, assertEquals (doble, doble) está obsoleto a partir de ahora y por buenas razones, así que le animo a que utilice el método con un delta como ya han sugerido otros.

Por buenas razones quiero decir que, dada la representación interna de números dobles, dos números dobles aparentemente iguales pueden diferir en una fracción infinitesimal irrelevante y no pasarían una prueba, pero eso no significa que haya algo malo en su código.

Fran Marzoa
fuente