Java JUnit: Metode X ambigu untuk tipe Y

98

Saya memiliki beberapa tes yang bekerja dengan baik. Kemudian, saya memindahkannya ke paket lain, dan sekarang saya mendapatkan kesalahan. Ini kodenya:

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

Pesan kesalahannya adalah ini:

Metode assertEquals (Object, Object) ambigu untuk tipe JGraphtUtilitiesTest

Bagaimana cara memperbaikinya? Mengapa masalah ini terjadi saat saya memindahkan kelas ke paket yang berbeda?

Nick Heiner
sumber
beri tahu kami bagaimana kelas Anda dideklarasikan. Tampak bagi saya seolah-olah Anda telah mewarisi dari JUnit3 dan kemudian mencoba mengimpor secara statis dari JUnit4.
bmargulies
ya, sebenarnya, saya memiliki JUnit3 di paket A, dan menggunakan JUnit4 di paket B, tempat saya awalnya menulis pengujian ini. Kemudian saya beralih dari Paket B ke Paket A, dan masalah muncul. Tapi saya tidak melihat apa pun di kelas ini yang menunjukkan JUnit 3. Di mana itu dideklarasikan?
Nick Heiner
@Rosarch Apakah JGraphtUtilities ini tersedia di mana saja? Saya tidak bisa melihat metode untuk menghasilkan eksentrisitas di JGraphT!
Nick

Jawaban:

205

Metode assertEquals (Object, Object) ambigu untuk tipe ...

Arti kesalahan ini adalah Anda meneruskan doubledan dan Doubleke dalam metode yang memiliki dua tanda tangan berbeda: assertEquals(Object, Object)dan assertEquals(double, double)keduanya dapat dipanggil, berkat autoboxing.

Untuk menghindari ambiguitas, pastikan Anda memanggil assertEquals(Object, Object)(dengan mengoper dua Ganda) atau assertEquals(double, double)(dengan mengoper dua Ganda ).

Jadi, dalam kasus Anda, Anda harus menggunakan:

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

Atau:

assertEquals(70.0d, eccen.get("alpha").doubleValue());
Pascal Thivent
sumber
ok, atau saya bisa langsung mengubahnya untuk menggunakan JUnit 4 daripada JUnit 3. Bagaimana cara melakukannya?
Nick Heiner
8
Solusinya tidak benar-benar beralih dari satu versi ke versi lainnya. Sebaliknya, bantu kompilator dan hapus ambiguitas seperti yang saya sarankan.
Pascal Thivent
1
Bagaimanapun, bukankah seharusnya assertEquals (70.0d, eccen.get ("alpha")); ?
mhaller
3
@mahller Tidak yakin dengan siapa Anda berbicara tetapi, meskipun kode itu lebih benar daripada kode OP, masih ambigu jika versi JUnit memiliki keduanya assertEquals(Object, Object)dan assertEquals(double, double)yang merupakan kasus JUnit 4.4, 4.5. Tetapi seperti yang saya katakan, mengubah versi JUnit bukanlah solusi nyata, perbaiki masalahnya.
Pascal Thivent
1
@Rosarch Untuk kasus khusus ini, ini bukan masalah di JUnit 3.8.1, ini bukan masalah di JUnit 4.3, ini masalah di JUnit 4.4, ini masalah di JUnit 4.5 (tetapi metode mengambil 2 doubles tidak digunakan lagi), ini bukan masalah di JUnit 4.6 (metode telah dihapus). Jadi, tentukan pilihan Anda, tetapi Anda harus memperbaiki kodenya.
Pascal Thivent
1

Anda bisa menggunakan metode ini

assertEquals(double expected, double actual, double delta)

Yang akan memperhitungkan kesalahan pembulatan yang mengarah ke floating point (lihat posting ini misalnya). Kamu bisa menulis

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

Ini berarti bahwa selama kedua nilai tersebut berbeda kurang dari 0,0001 maka keduanya dianggap sama. Ini memiliki dua keuntungan:

  • Membandingkan nilai floating point sebagaimana mestinya
  • Tidak perlu dilemparkan, karena tiga argumen menegaskan hanya berlaku untuk ganda, bukan untuk Objek generik
Paolo
sumber
0

Solusi paling sederhana untuk masalah ini adalah dengan mengubah parameter kedua menjadi primitif:

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

Ambiguitas dihapus.

Ini berlaku untuk salah satu subkelas Number, misalnya:

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

Akan memecahkan ambiguitas juga.

Namun, assertEquals (double, double) tidak digunakan lagi sekarang dan untuk alasan yang baik, jadi saya mendorong Anda untuk menggunakan metode dengan delta seperti yang disarankan orang lain.

Maksud saya, dengan alasan yang baik, mengingat representasi bagian dalam dari angka ganda, dua angka ganda yang tampaknya sama dapat berbeda dalam pecahan sangat kecil yang tidak relevan dan tidak akan lulus ujian, tetapi itu tidak berarti ada yang salah dengan kode Anda.

Fran Marzoa
sumber