Java JUnit: il metodo X è ambiguo per il tipo Y


98

Ho fatto funzionare bene alcuni test. Quindi, l'ho spostato in un pacchetto diverso e ora sto ricevendo errori. Ecco il codice:

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"));
    }

Il messaggio di errore è questo:

Il metodo assertEquals (Object, Object) è ambiguo per il tipo JGraphtUtilitiesTest

Come posso risolvere questo problema? Perché questo problema si è verificato quando ho spostato la classe in un pacchetto diverso?


dicci come viene dichiarata la tua classe. Mi sembra che tu abbia ereditato da JUnit3 e poi abbia provato a importare staticamente da JUnit4.
bmargulies

sì, in realtà, avevo JUnit3 nel pacchetto A e utilizzavo JUnit4 nel pacchetto B, dove originariamente avevo scritto questi test. Quindi sono passato dal pacchetto B al pacchetto A e il problema è sorto. Ma non vedo nulla in questa classe che indicherebbe JUnit 3. Dove è dichiarato?
Nick Heiner,

@Rosarch Queste JgraphtUtilities sono disponibili ovunque? Non riesco a vedere metodi per produrre eccentricità in JgraphT!
Nick

Risposte:


205

Il metodo assertEquals (Object, Object) è ambiguo per il tipo ...

Ciò che questo errore significa è che stai passando un doublee Doublein un metodo che ha due firme diverse: assertEquals(Object, Object)ed assertEquals(double, double)entrambe possono essere chiamate, grazie all'autoboxing.

Per evitare l'ambiguità, assicurati di chiamare assertEquals(Object, Object)(passando due doppi) o assertEquals(double, double)(passando due doppi).

Quindi, nel tuo caso, dovresti usare:

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

O:

assertEquals(70.0d, eccen.get("alpha").doubleValue());

ok, o potrei semplicemente cambiarlo per usare JUnit 4 invece di JUnit 3. Come posso farlo?
Nick Heiner

8
La soluzione non è realmente passare da una versione all'altra. Invece, aiuta il compilatore e rimuovi l'ambiguità come ho suggerito.
Pascal Thivent

1
Comunque, non dovrebbe essere assertEquals (70.0d, eccen.get ("alpha")); ?
mhaller

3
@mahller Non sono sicuro con chi stai parlando ma, anche se è più corretto del codice dell'OP, è ancora ambiguo se la versione di JUnit ha entrambi assertEquals(Object, Object)e assertEquals(double, double)che è il caso di JUnit 4.4, 4.5. Ma come ho detto, cambiare la versione di JUnit non è la vera soluzione, basta risolvere il problema.
Pascal Thivent

1
@Rosarch Per questo caso particolare, non è un problema in JUnit 3.8.1, non è un problema in JUnit 4.3, è un problema in JUnit 4.4, è un problema in JUnit 4.5 (ma il metodo che prende 2 doubles è deprecato), non è un problema in JUnit 4.6 (il metodo è stato rimosso). Quindi, fai la tua scelta, ma dovresti correggere il codice.
Pascal Thivent

1

Puoi usare il metodo

assertEquals(double expected, double actual, double delta)

Che terrà conto dell'errore di arrotondamento che è inerente al punto mobile (vedi questo post per esempio). Tu puoi scrivere

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

Ciò significa che fintanto che i due valori differiscono per meno di 0,0001 sono considerati uguali. Questo ha due vantaggi:

  • Confronta i valori in virgola mobile come dovrebbero
  • Non è necessario eseguire il cast, poiché i tre argomenti asseriscono si applicano solo ai doppi, non agli oggetti generici

0

La soluzione più semplice a questo problema è semplicemente lanciare il secondo parametro in una primitiva:

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

Ambiguità rimossa.

Questo è valido per qualsiasi sottoclasse Number, ad esempio:

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

Risolverebbe anche un'ambiguità.

Tuttavia, assertEquals (double, double) è sconsigliato al momento e per buoni motivi, quindi ti incoraggio a utilizzare il metodo con un delta come altri hanno già suggerito.

Per buone ragioni intendo che, data la rappresentazione interna dei numeri doppi, due numeri doppi apparentemente uguali possono differire in una frazione infinitesimale irrilevante e non supererebbero un test, ma ciò non significa che ci sia qualcosa di sbagliato nel tuo codice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.