Java JUnit: o método X é ambíguo para o tipo Y

98

Eu tive alguns testes funcionando bem. Em seguida, mudei para um pacote diferente e agora estou recebendo erros. Aqui está o 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"));
    }

A mensagem de erro é esta:

O método assertEquals (Object, Object) é ambíguo para o tipo JGraphtUtilitiesTest

Como posso consertar isso? Por que esse problema ocorreu quando mudei a classe para um pacote diferente?

Nick Heiner
fonte
diga-nos como sua classe é declarada. Parece-me que você herdou de JUnit3 e depois tentou importar estaticamente de JUnit4.
bmargulies
sim, na verdade, eu tinha JUnit3 no pacote A e usei JUnit4 no pacote B, onde originalmente escrevi esses testes. Então mudei do Pacote B para o Pacote A, e o problema surgiu. Mas não vejo nada nesta classe que indique JUnit 3. Onde isso está declarado?
Nick Heiner
@Rosarch Esses JGraphtUtilities estão disponíveis em algum lugar? Não consigo ver métodos para produzir excentricidades no JGraphT!
Nick

Respostas:

205

O método assertEquals (Object, Object) é ambíguo para o tipo ...

O que esse erro significa é que você está passando um doublee e Doublepara um método que possui duas assinaturas diferentes: assertEquals(Object, Object)e assertEquals(double, double)ambas podem ser chamadas, graças ao autoboxing.

Para evitar a ambigüidade, certifique-se de chamar assertEquals(Object, Object)(passando duas duplas) ou assertEquals(double, double)(passando duas duplas).

Portanto, no seu caso, você deve usar:

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

Ou:

assertEquals(70.0d, eccen.get("alpha").doubleValue());
Pascal Thivent
fonte
ok, ou eu poderia apenas alterná-lo para usar o JUnit 4 em vez do JUnit 3. Como faço isso?
Nick Heiner
8
A solução não é realmente mudar de uma versão para a outra. Em vez disso, ajude o compilador e remova a ambiguidade como sugeri.
Pascal Thivent
1
De qualquer forma, não deveria ser assertEquals (70.0d, eccen.get ("alpha")); ?
mhaller
3
@mahller Não tenho certeza com quem você está falando, mas, mesmo que seja mais correto que o código do OP, ainda é ambíguo se a versão do JUnit tem ambos assertEquals(Object, Object)e assertEquals(double, double)que é o caso do JUnit 4.4, 4.5. Mas como eu disse, mudar a versão do JUnit não é a solução real, apenas conserte o problema.
Pascal Thivent
1
@Rosarch Para este caso particular, não é um problema no JUnit 3.8.1, não é um problema no JUnit 4.3, é um problema no JUnit 4.4, é um problema no JUnit 4.5 (mas o método leva 2 doubles está obsoleto), não é um problema no JUnit 4.6 (o método foi removido). Portanto, faça sua escolha, mas você deve corrigir o código.
Pascal Thivent
1

Você pode usar o método

assertEquals(double expected, double actual, double delta)

O que levará em conta os erros de arredondamento que são hinerentes ao ponto flutuante (veja este post por exemplo). Você pode escrever

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

Isso significa que, desde que os dois valores sejam diferentes por menos de 0,0001, eles são considerados iguais. Isso tem duas vantagens:

  • Compara valores de ponto flutuante como deveriam
  • Não há necessidade de lançar, como os três argumentos afirmam se aplica apenas a duplos, não a objetos genéricos
Paolo
fonte
0

A solução mais simples para esse problema é apenas converter o segundo parâmetro em uma primitiva:

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

Ambiguidade removida.

Isso é válido para qualquer uma das subclasses de Number, por exemplo:

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

Também resolveria uma ambigüidade.

No entanto, assertEquals (double, double) está obsoleto a partir de agora e por boas razões, então eu encorajo você a usar o método com um delta como outros já sugeriram.

Por boas razões, quero dizer que, dada a representação interna dos números duplos, dois números duplos aparentemente iguais podem diferir em uma fração infinitesimal irrelevante e não passariam no teste, mas isso não significa que há algo errado com seu código.

Fran Marzoa
fonte