Junit4: Peningkatan: Dukungan BigDecimal untuk assertEquals()

Dibuat pada 25 Mar 2010  ·  27Komentar  ·  Sumber: junit-team/junit4

Menggunakan JUnit untuk menguji nilai BigDecimal selalu menjadi masalah. Itu karena BigDecimal menganggap presisi menggunakan equals() tetapi mengabaikannya di compareTo(). Cara terbaik untuk menangani ini adalah metode assertEquals baru yang memungkinkan presisi dievaluasi secara opsional. Anda juga dapat menambahkan metode alternatif yang menerima pesan:

public static void assertEquals(BigDecimal diharapkan, BigDecimal aktual, boolean precisionMatters) {
if (PrecisionMatters) {
Assert.assertEquals(diharapkan, aktual);
} lain {
Assert.assertEquals(0, diharapkan.compareTo(aktual));
}
}

feature

Komentar yang paling membantu

Sudahkah Anda mencoba menggunakan comparesEqualTo ?

Semua 27 komentar

Akan menjadi hal yang mudah untuk disatukan sebagai garpu atau tambalan; Saya bersedia melakukannya jika perlu.

Saya lebih suka memiliki pernyataan assertNumericallyEqualTo daripada flag boolean yang diteruskan ke assertEquals.

Itu nama yang bagus. Saya akan mempersingkatnya menjadi assertNumericallyEquals().

Meskipun saya setuju dengan sentimen tersebut, saya tidak yakin memiliki metode penegasan lain dengan nama yang berbeda akan sangat membantu menghilangkan kebingungan terutama di antara orang-orang yang sama sekali tidak menyadari perbedaannya atau belum benar-benar mengalami masalah itu sendiri. Maksud saya, jika saya tidak membaca masalah ini, saya akan melanjutkan dan menggunakan assertEquals() untuk BigDecimal . Dalam kasus umum, sebenarnya, ini akan berfungsi seperti yang diiklankan—ini akan bekerja persis seperti BigDecimal#equals() bekerja. Saya bahkan berpendapat bahwa ini adalah hal yang baik—itu memaksa seseorang untuk menyadari bahwa BigDecimal#equals() membandingkan nilai dan skala, maka mungkin itu bukan yang mereka coba capai—meskipun, dalam kasus lain, saya berpendapat itu _adalah_. Maksud saya, dalam beberapa kasus kami ingin memeriksa bahwa nilai aktual yang dikembalikan oleh suatu metode adalah _persis_ 'sama' dengan nilai yang diharapkan (bukan hanya sama secara logis/numerik). Dengan kata lain: apa yang assertNumericallyEquals() berikan (selain singkatnya) yang tidak diberikan oleh assertEquals(0, actual.compareTo(expected)) ? Secara pribadi, saya mungkin akan membuat Hamcrest matcher dan pergi assertThat(actual, isNumericallyEqualTo(expected)) jika saya membutuhkannya cukup sering—plus, dapat digunakan di mana saja Hamcrest matcher dapat digunakan (validasi data, antara lain).

Maaf untuk penimbangan yang terlambat, tetapi pendapat pribadi saya hampir sama dengan pendapat Alistair.

Dengan kata lain: apa yang assertNumericallyEquals() berikan (selain singkatnya) yang tidak assertEquals(0, actual.compareTo(expected)) ?

Mengkomunikasikan niat lebih jelas? Pendekatan pencocokan hamcrest baik-baik saja dengan saya.

Geoffrey,

Apakah Anda mengatakan bahwa Anda baik-baik saja menulis korek api itu untuk proyek Anda sendiri, atau Anda ingin itu dikirimkan dengan hamcrest? Atau JUnit, tapi bukan hamcrest?

Salah satu atau semua hal di atas -- sebagian besar proyek yang saya tulis akhirnya memiliki beberapa pencocokan hamcrest khusus. Memiliki kasus umum yang dicakup oleh Hamcrest dan/atau JUnit menghemat sedikit waktu, tetapi ini juga bukan kasus yang sangat umum bagi saya.

Poin kecil tentang pesan kesalahan yang kurang berguna.. Saya baru saja mengonversi panggilan Assert.assertEquals saya ke Assert.assertTrue karena gagal dalam membandingkan BigDecimals dengan Assert.assertEquals. Tentu saja sekarang pengujian saya gagal dengan semacam kesalahan "pengujian boolean gagal", tanpa memberi tahu saya apa nilainya. Dengan cara yang sama, assertEquals(0, actual.compareTo(expected)) akan mencatat misalnya "expected 0 but got: 1" ketika pesan kesalahan yang jauh lebih berguna berasal dari assertNumericallyEquals(actual, expected) akan menjadi "expected 12.45 but got : 123" (nilai aktual dari argumen 'aktual' dan 'yang diharapkan').

http://www.bssd.eu/blog/?p=113 membuat bacaan yang menarik juga.

assertEquivalent dari https://github.com/KentBeck/junit/pull/228 harus menyelesaikan ini.

Terima kasih dsaf. Pekerjaan itu tampak hebat. Saya belum pernah melakukan ini sebelumnya, apakah ini berarti saya harus mengambil sumber junit, menggabungkan sendiri permintaan tarik ini, dan membuat build khusus?

Dari bantuan di http://help.github.com/send-pull-requests/ sepertinya saya harus:

git clone https://github.com/KentBeck/junit.git
cd junit

lalu tambahkan remote untuk permintaan tarik, lalu ambil, gabungkan, atau lakukan keduanya.

Mengingat bahwa ini tampaknya merupakan permintaan tarik yaitu bukan junit resmi, apakah bijaksana untuk digunakan dalam aplikasi? Adakah kemungkinan ini akan terbentuk di luar junit utama, dan saya akan mengalami masalah dalam mengirim kode saya ke orang lain, untuk siapa itu tidak akan dibangun?

Neekfenwick,

Ya, Anda berada di jalur yang benar tentang bagaimana melakukannya sekarang. Saya bermaksud menggabungkan tarikan itu ke cabang 4.10, tetapi penulis aslinya mengalami kesulitan mendapatkan status git yang dapat digabung. Jika Anda punya waktu untuk membantu dunia, Anda dapat membayar repo KentBeck, menggabungkan semuanya, dan mengeluarkan permintaan tarik terhadap cabang 4.10, sehingga akan lebih mudah bagi semua orang (jika kedengarannya populer, saya bahkan dapat memutar up kadang-kadang toples pratinjau 4.10).

Saya benar-benar belum pernah melakukan ini sebelumnya :) Jadi saya telah melakukan fork repo dan mengkloning [email protected] :neekfenwick/junit.git ke mesin lokal saya (saya sudah memiliki akun github dan kunci ssh diatur), dan menambahkan remote untuk repo tempat saya mengambilnya:

git remote add upstream https://github.com/KentBeck/junit.git

Hanya untuk ukuran yang baik, saya telah bercabang sehingga saya dapat menggabungkan permintaan tarik ke tempat lain selain HEAD:

git branch merge_pullreq_228
git checkout merge_pullreq_228

Sekarang dokumen yang dapat saya temukan mengatakan "sekarang gabungkan permintaan tarik ke cabang Anda". Saya dapat melihat komit untuk pull 228 di https://github.com/KentBeck/junit/pull/228/commits tetapi saya tidak dapat menggabungkannya:

[neek junit (merge_pullreq_228)]$ git merge 57b49344
fatal: '57b49344' does not point to a commit

Karena permintaan tarik bukan untuk repo/cabang saya sendiri, saya tidak dapat menggunakan alat Gabung di github web gui (AFAIK).

Apakah saya benar dalam berpikir Anda ingin saya menggabungkan 7 komit ke dalam cabang saya sendiri dan membuatnya untuk membangun/lulus tes unit? Bisakah Anda menjelaskan apa yang harus dilakukan untuk menggabungkan salah satu dari komitmen ini untuk membuat saya dalam perjalanan?

Benar, Anda tidak dapat menggunakan alat penggabungan web. Apa yang saya yakini harus berhasil adalah:

git remote tambahkan leet3lite https://github.com/leet3lite/junit.git

Dan kemudian dari cabang Anda, hubungi

git pull master leet3lite

Sayangnya, saya biasanya lupa satu hal ketika menjelaskan cara menggunakan git "melalui telepon", jadi beri tahu saya jika itu berhasil untuk Anda.

Ah begitu, saya tidak perlu menggabungkan masing-masing komit itu.. cabang master leet3lite sudah memilikinya, dan tindakan menggabungkan pekerjaan itu ke master asli itulah masalahnya.

Tampaknya ada konflik gabungan antara cabang itu dan HEAD. Saya rasa itulah inti dari latihan ini.

[neek junit (merge_pullreq_228)]$ git remote add leet3lite https://github.com/leet3lite/junit.git
[neek junit (merge_pullreq_228)]$ git pull leet3lite master
remote: Counting objects: 100, done.
remote: Compressing objects: 100% (39/39), done.
remote: Total 85 (delta 34), reused 77 (delta 26)
Unpacking objects: 100% (85/85), done.
From https://github.com/leet3lite/junit
 * branch            master     -> FETCH_HEAD
Auto-merging acknowledgements.txt
CONFLICT (content): Merge conflict in acknowledgements.txt
Auto-merging src/main/java/org/junit/Assert.java
Auto-merging src/test/java/org/junit/tests/AllTests.java
CONFLICT (content): Merge conflict in src/test/java/org/junit/tests/AllTests.java
Automatic merge failed; fix conflicts and then commit the result.
[neek junit (merge_pullreq_228|MERGING)]$ 

Jika itu terlihat masuk akal bagi Anda, saya akan melanjutkannya besok. Hampir tengah malam di sini.

Sepertinya Anda berada di tempat yang tepat. pengakuan.txt dan AllTests.java sering disentuh, biasanya hanya dengan menambahkan, jadi operasi penggabungan mungkin merupakan tindakan sederhana dengan memasukkan semua baris yang ditambahkan di kedua jalur.

Terima kasih banyak telah mendorong ini ke depan.

Saya pikir ini sudah diperbaiki 2 tahun yang lalu.

dsaff --Tidak...?

Tidak di 4.11 ;( Saya juga membutuhkan fitur ini

Diskusi tentang assertEquivalent() pindah ke #228 dan setelah itu, saya pikir itu pindah ke #376 di mana kami memutuskan bahwa Hamcrest harus menyelesaikan ini.

@junit-team/junit-committers ada keberatan saya menutup ini?

Tidak ada keberatan dari pihak saya.

Ups, klik Freudian. :-) Tidak ada keberatan di sini.

Oke. Penutupan kemudian.

Saya tidak berpikir menggunakan hamcrest matcher memperbaiki masalah ini. Misalnya kode ini:

   assertThat(product.getRating(), is(equalTo(new BigDecimal("2.3"))));

akan menghasilkan hasil ini:

Expected: is <2.3>
     but: was <2.30000>

Saya pikir junit atau hamcrest masih membutuhkan metode isNumericEquivalent .

Sudahkah Anda mencoba menggunakan comparesEqualTo ?

Ya, comparesEqualTo benar-benar berfungsi. Terima kasih.

Berikut contekan yang saya buat beberapa waktu lalu:
http://www.marcphilipp.de/blog/2013/01/02/hamcrest-quick-reference/

Apakah halaman ini membantu?
0 / 5 - 0 peringkat