Saya mencoba menegaskan bahwa satu objek "sama" dengan objek lain.
Objek hanya contoh kelas dengan banyak properti publik. Apakah ada cara mudah untuk meminta NUnit menegaskan kesetaraan berdasarkan propertinya?
Ini adalah solusi saya saat ini tetapi saya pikir mungkin ada sesuatu yang lebih baik:
Assert.AreEqual(LeftObject.Property1, RightObject.Property1)
Assert.AreEqual(LeftObject.Property2, RightObject.Property2)
Assert.AreEqual(LeftObject.Property3, RightObject.Property3)
...
Assert.AreEqual(LeftObject.PropertyN, RightObject.PropertyN)
Apa yang akan saya lakukan adalah dalam semangat yang sama dengan CollectionEquivalentConstraint di mana NUnit memverifikasi bahwa isi dari dua koleksi adalah sama.
sumber
IEnumerable
akan dibandingkan sebagai koleksi tanpa mengesampingkan implementasiEquals
karena NUnit memberikanIEnumerable
prioritas lebih tinggi. LihatNUnitEqualityComparer.AreEqual
metode untuk detailnya. Anda dapat mengganti pembanding dengan menggunakan salah satuUsing()
metode kendala kesetaraan . Meski begitu, itu tidak cukup untuk mengimplementasikan non-generikIEqualityComparer
karena NUnit menggunakan adaptor.GetHashCode()
pada tipe yang bisa berubah akan berperilaku salah jika Anda pernah menggunakan objek itu sebagai kunci. IMHO, mengesampingkanEquals()
,GetHashCode()
dan membuat objek tidak berubah hanya untuk pengujian tidak masuk akal.Jika Anda tidak dapat mengesampingkan Equals karena alasan apa pun, Anda dapat membangun metode pembantu yang beralih melalui properti publik dengan merefleksikan dan menegaskan setiap properti. Sesuatu seperti ini:
sumber
Jangan menimpa Sama dengan hanya untuk tujuan pengujian. Itu membosankan dan memengaruhi logika domain. Sebagai gantinya,
Gunakan JSON untuk membandingkan data objek
Tidak ada logika tambahan pada objek Anda. Tidak ada tugas tambahan untuk pengujian.
Cukup gunakan metode sederhana ini:
Tampaknya berhasil dengan baik. Info hasil pelari uji akan menampilkan perbandingan string JSON (grafik objek) yang disertakan sehingga Anda dapat melihat secara langsung apa yang salah.
Juga mencatat! Jika Anda memiliki objek kompleks yang lebih besar dan hanya ingin membandingkan bagian-bagiannya, Anda dapat ( menggunakan LINQ untuk data urutan ) membuat objek anonim untuk digunakan dengan metode di atas.
sumber
Coba pustaka FluentAssertions:
http://www.fluentassertions.com/
Itu juga dapat diinstal menggunakan NuGet.
sumber
actual.ShouldBeEquivalentTo(expected, x => x.ExcludingMissingMembers())
Saya lebih suka untuk tidak mengabaikan Equals hanya untuk mengaktifkan pengujian. Jangan lupa bahwa jika Anda mengesampingkan Equals Anda benar-benar harus menimpa GetHashCode juga atau Anda mungkin mendapatkan hasil yang tidak terduga jika Anda menggunakan objek Anda dalam kamus misalnya.
Saya suka pendekatan refleksi di atas karena melayani penambahan properti di masa depan.
Untuk solusi cepat dan sederhana namun seringkali paling mudah untuk membuat metode pembantu yang menguji apakah objeknya sama, atau mengimplementasikan IEqualityComparer di kelas yang Anda jaga pribadi untuk tes Anda. Saat menggunakan solusi IEqualityComparer Anda tidak perlu repot dengan implementasi GetHashCode. Sebagai contoh:
sumber
Saya sudah mencoba beberapa pendekatan yang disebutkan di sini. Sebagian besar melibatkan serialisasi objek Anda dan melakukan perbandingan string. Meskipun super mudah dan umumnya sangat efektif, saya menemukan sedikit kekurangan ketika Anda mengalami kegagalan dan sesuatu seperti ini dilaporkan:
Mencari tahu di mana perbedaan itu merupakan rasa sakit untuk sedikitnya.
Dengan perbandingan grafik objek FluentAssertions ' (yaitu
a.ShouldBeEquivalentTo(b)
), Anda mendapatkan ini kembali:Itu jauh lebih baik. Dapatkan FluentAssertions sekarang, Anda akan senang nanti (dan jika Anda memperbaiki ini, harap juga upvote jawaban dkl di mana FluentAssertions pertama kali disarankan).
sumber
Saya setuju dengan ChrisYoxall - menerapkan Equals dalam kode utama Anda murni untuk tujuan pengujian tidak baik.
Jika Anda menerapkan Equals karena beberapa logika aplikasi mengharuskannya, maka itu tidak masalah, tetapi jauhkan kode hanya pengujian murni dari hal-hal yang berantakan (juga semantik pemeriksaan yang sama untuk pengujian mungkin berbeda dari yang dibutuhkan aplikasi Anda).
Singkatnya, jauhkan kode khusus pengujian dari kelas Anda.
Perbandingan dangkal sederhana dari properti yang menggunakan refleksi harus cukup untuk sebagian besar kelas, meskipun Anda mungkin perlu berulang jika objek Anda memiliki sifat kompleks. Jika mengikuti referensi, waspadalah terhadap referensi melingkar atau serupa.
Licik
sumber
Kendala properti , ditambahkan dalam NUnit 2.4.2, memungkinkan solusi yang lebih mudah dibaca daripada yang asli OP, dan menghasilkan pesan kegagalan yang jauh lebih baik. Ini tidak generik, tetapi jika Anda tidak perlu melakukannya untuk kelas terlalu banyak, itu solusi yang sangat memadai.
Bukan sebagai tujuan umum sebagai implementasi
Equals
tetapi memberikan pesan kegagalan yang jauh lebih baik daripadasumber
Solusi JSON Max Wikstrom (di atas) paling masuk akal bagi saya, singkat, bersih, dan yang terpenting berfungsi. Secara pribadi saya lebih suka untuk mengimplementasikan konversi JSON sebagai metode terpisah dan menempatkan pernyataan kembali di dalam unit test seperti ini ...
METODE BANTUAN:
UJI UNIT:
FYI - Anda mungkin perlu menambahkan referensi ke System.Web.Extensions dalam solusi Anda.
sumber
Ini adalah utas yang cukup lama tetapi saya bertanya-tanya apakah ada alasan mengapa tidak ada jawaban yang diajukan
NUnit.Framework.Is.EqualTo
danNUnit.Framework.Is.NotEqualTo
?Seperti:
dan
sumber
Pilihan lain adalah untuk menulis batasan kustom dengan mengimplementasikan
Constraint
kelas abstrak NUnit . Dengan kelas penolong untuk menyediakan sedikit gula sintaksis, kode uji yang dihasilkan menyenangkan dan mudah dibaca misalnyaSebagai contoh ekstrem, anggap kelas yang memiliki anggota 'baca-saja' tidak
IEquatable
, dan Anda tidak dapat mengubah kelas yang sedang diuji bahkan jika Anda ingin:Kontrak untuk
Constraint
kelas mengharuskan seseorang untuk menimpaMatches
danWriteDescriptionTo
(dalam kasus ketidakcocokan, narasi untuk nilai yang diharapkan) tetapi juga mengesampingkanWriteActualValueTo
(narasi untuk nilai aktual) masuk akal:Ditambah kelas pembantu:
Contoh penggunaan:
sumber
Saya akan membangun jawaban dari @Juanma. Namun, saya percaya ini tidak boleh diimplementasikan dengan pernyataan unit test. Ini adalah utilitas yang dapat digunakan dalam beberapa keadaan dengan kode non-tes.
Saya menulis artikel tentang hal ini http://timoch.com/blog/2013/06/unit-test-equality-is-not-domain-equality/
Proposal saya adalah sebagai berikut:
Menggunakan ini dengan NUnit
menghasilkan pesan berikut pada ketidakcocokan.
sumber
https://github.com/kbilsted/StatePrinter telah ditulis khusus untuk membuang grafik objek ke representasi string dengan tujuan menulis unit test yang mudah.
Diberikan
Anda dapat mengetik dengan cara yang aman, dan menggunakan penyelesaian otomatis studio visual termasuk atau mengecualikan bidang.
sumber
Cukup instal ExpectedObjects dari Nuget, Anda dapat dengan mudah membandingkan nilai properti dua objek, setiap nilai objek koleksi, dua nilai objek yang dikomposisikan dan membandingkan sebagian nilai properti dengan jenis anonim.
Saya punya beberapa contoh di github: https://github.com/hatelove/CompareObjectEquals
Berikut adalah beberapa contoh yang berisi skenario membandingkan objek:
Referensi:
sumber
Lihatlah tautan berikut. Ini solusi dari proyek kode dan saya telah menggunakannya juga. Ini berfungsi dengan baik untuk membandingkan objek.
http://www.codeproject.com/Articles/22709/Testing-Equality-of-Two-Objects?msg=5189539#xx5189539xx
sumber
Saya telah mengakhiri dengan menulis sebuah pabrik ekspresi sederhana:
dan gunakan saja:
Ini sangat berguna karena saya harus membandingkan koleksi benda-benda tersebut. Dan Anda dapat menggunakan pembanding ini di tempat lain :)
Berikut adalah intinya dengan contoh: https://gist.github.com/Pzixel/b63fea074864892f9aba8ffde312094f
sumber
Deserialize kedua kelas, dan lakukan perbandingan string.
EDIT: Berfungsi sempurna, ini adalah output yang saya dapatkan dari NUnit;
EDIT DUA: Kedua objek bisa identik, tetapi urutan properti serial tidak sama. Karena itu XML berbeda. DOH!
EDIT TIGA: Ini berhasil. Saya menggunakannya dalam tes saya. Tetapi Anda harus menambahkan item ke properti koleksi dalam urutan kode yang diuji menambahkannya.
sumber
Saya tahu ini adalah pertanyaan yang sangat lama, tetapi NUnit masih belum memiliki dukungan asli untuk ini. Namun, jika Anda menyukai pengujian gaya BDD (ala Jasmine), Anda akan terkejut dengan NExpect ( https://github.com/fluffynuts/NExpect , dapatkan dari NuGet), yang memiliki pengujian kesetaraan mendalam yang dipanggang tepat di sana .
(Penafian: Saya penulis NExpect)
sumber
Merangkan dan membandingkan dua string
Assert.AreEqual (JSON.stringify (LeftObject), JSON.stringify (RightObject))
sumber
sumber