Java JUnit: la méthode X est ambiguë pour le type Y

98

J'ai eu quelques tests fonctionnant bien. Ensuite, je l'ai déplacé vers un autre package et je reçois maintenant des erreurs. Voici le code:

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

Le message d'erreur est le suivant:

La méthode assertEquals (Object, Object) est ambiguë pour le type JGraphtUtilitiesTest

Comment puis-je réparer cela? Pourquoi ce problème s'est-il produit lorsque j'ai déplacé la classe vers un autre package?

Nick Heiner
la source
dites-nous comment votre classe est déclarée. Il me semble que vous avez hérité de JUnit3 et que vous avez ensuite essayé d'importer statiquement de JUnit4.
bmargulies
ouais, en fait, j'avais JUnit3 dans le package A et utilisé JUnit4 dans le package B, où j'ai écrit ces tests à l'origine. Ensuite, je suis passé du package B au package A, et le problème est survenu. Mais je ne vois rien dans cette classe qui indiquerait JUnit 3. Où est-ce déclaré?
Nick Heiner
@Rosarch Ces JGraphtUtilities sont-ils disponibles n'importe où? Je ne vois pas de méthodes pour produire des excentricités dans JGraphT!
Nick

Réponses:

205

La méthode assertEquals (Object, Object) est ambiguë pour le type ...

Ce que cette erreur signifie, c'est que vous passez un doubleand et Doubledans une méthode qui a deux signatures différentes: assertEquals(Object, Object)et assertEquals(double, double)qui peuvent toutes deux être appelées, grâce à l'autoboxing.

Pour éviter toute ambiguïté, assurez-vous que vous appelez assertEquals(Object, Object)(en passant deux doubles) ou assertEquals(double, double)(en passant deux doubles).

Donc, dans votre cas, vous devriez utiliser:

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

Ou:

assertEquals(70.0d, eccen.get("alpha").doubleValue());
Pascal Thivent
la source
ok, ou je pourrais simplement le changer pour utiliser JUnit 4 au lieu de JUnit 3. Comment faire cela?
Nick Heiner
8
La solution n'est pas vraiment de passer d'une version à l'autre. Au lieu de cela, aidez le compilateur et supprimez l'ambiguïté comme je l'ai suggéré.
Pascal Thivent
1
Quoi qu'il en soit, ne devrait-il pas être assertEquals (70.0d, eccen.get ("alpha")); ?
mhaller
3
@mahller Je ne sais pas à qui vous parlez mais, même si c'est plus correct que le code de l'OP, il reste ambigu si la version de JUnit a les deux assertEquals(Object, Object)et assertEquals(double, double)ce qui est le cas de JUnit 4.4, 4.5. Mais comme je l'ai dit, changer la version de JUnit n'est pas la vraie solution, il suffit de résoudre le problème.
Pascal Thivent
1
@Rosarch Pour ce cas particulier, il est pas un problème dans JUnit 3.8.1, ce n'est pas un problème dans JUnit 4.3, il est un problème dans JUnit 4.4, il est un problème dans JUnit 4.5 (mais la méthode prenant 2 doubles est obsolète), ce n'est pas un problème dans JUnit 4.6 (la méthode a été supprimée). Alors, faites votre choix, mais vous devez corriger le code.
Pascal Thivent
1

Vous pouvez utiliser la méthode

assertEquals(double expected, double actual, double delta)

Ce qui prendra en compte les erreurs d'arrondi qui sont hinerent à virgule flottante (voir cet article par exemple). Tu peux écrire

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

Cela signifie que tant que les deux valeurs diffèrent pour moins de 0,0001, elles sont considérées comme égales. Cela présente deux avantages:

  • Compare les valeurs en virgule flottante comme elles sont supposées
  • Pas besoin de transtyper, car l'assertion des trois arguments ne s'applique qu'aux doubles, pas aux objets génériques
Paolo
la source
0

La solution la plus simple à ce problème consiste simplement à convertir le deuxième paramètre en une primitive:

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

Ambiguïté supprimée.

Ceci est valable pour toutes les sous-classes Number, par exemple:

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

Cela résoudrait aussi une ambiguïté.

Cependant, assertEquals (double, double) est obsolète pour le moment et pour de bonnes raisons, je vous encourage donc à utiliser la méthode avec un delta comme d'autres l'ont déjà suggéré.

Par bonnes raisons, je veux dire que, étant donné la représentation interne des nombres doubles, deux nombres doubles apparemment égaux peuvent différer dans une fraction infinitésimale non pertinente et ne passeraient pas un test, mais cela ne signifie pas qu'il y a quelque chose qui ne va pas avec votre code.

Fran Marzoa
la source