xUnit: Tegaskan dua Daftar <T> sama?

109

Saya baru mengenal TDD dan xUnit jadi saya ingin menguji metode saya yang terlihat seperti:

List<T> DeleteElements<T>(this List<T> a, List<T> b);

Apakah ada metode Assert yang dapat saya gunakan? Saya pikir hal seperti ini akan menyenangkan

List<int> values = new List<int>() { 1, 2, 3 };
List<int> expected = new List<int>() { 1 };
List<int> actual = values.DeleteElements(new List<int>() { 2, 3 });

Assert.Exact(expected, actual);

Apa ada yang seperti ini?

Petar Petrov
sumber

Jawaban:

136

xUnit.Net mengenali koleksi jadi Anda hanya perlu melakukannya

Assert.Equal(expected, actual); // Order is important

Anda dapat melihat pernyataan koleksi lain yang tersedia di CollectionAsserts.cs

Untuk metode perbandingan koleksi perpustakaan NUnit adalah

CollectionAssert.AreEqual(IEnumerable, IEnumerable) // For sequences, order matters

dan

CollectionAssert.AreEquivalent(IEnumerable, IEnumerable) // For sets, order doesn't matter

Lebih jelasnya di sini: CollectionAssert

MbUnit juga memiliki pernyataan koleksi yang mirip dengan NUnit: Assert.Collections.cs

Konstantin Spirin
sumber
1
Tautan kode sumber diubah untuk xunit.codeplex.com/SourceControl/changeset/view/…
Julien Roncaglia
1
Tautan baru di komentar juga rusak.
Scott Stafford
1
Project sekarang dipindahkan ke GitHub, tetapi saya juga belum dapat menemukan file sumber tertentu di sana.
MEMark
1
Untuk objek kompleks, jangan lupa bahwa Anda memerlukan Equal + GetHasCode agar ini berfungsi atau berikan metode Equal EqulityComparer kustom
maracuja-juice
2
xUnit Equal method mengembalikan nilai false untuk dua IEnumerables dengan konten yang sama.
Vladimir Kocjancic
31

Dalam versi XUnit (1.5) saat ini, Anda dapat menggunakan

Assert.Equal (diharapkan, aktual);

Metode di atas akan melakukan perbandingan elemen dengan elemen dari dua daftar. Saya tidak yakin apakah ini berfungsi untuk versi sebelumnya.

hwiechers
sumber
7
Masalah yang saya temui dengan Assert.Equal untuk koleksi adalah gagal jika elemen koleksi berada dalam urutan berbeda, bahkan jika elemen ada di keduanya.
Scott Lawrence
1
@ ScottA. Daftar Lawrence juga dipesan! Apakah Anda mendapatkan perilaku yang sama dengan HashSets?
johv
@johv Saya belum mengujinya dengan HashSets, tapi itu ide yang bagus. Setelah saya memiliki kesempatan untuk mencobanya, saya akan mencoba mengingat untuk menjawab di sini.
Scott Lawrence
2
Tampaknya juga gagal jika jenis koleksi berbeda, meskipun keduanya berisi item yang sama dalam urutan yang sama.
James White
3
Tapi hasilnya sangat jelek. Ini tidak memberi tahu Anda DI MANA dua daftar berbeda! :(
Zordid
16

Dengan xUnit, jika Anda ingin memilih properti dari setiap elemen yang akan diuji, Anda dapat menggunakan Assert.Collection.

Assert.Collection(elements, 
  elem1 => Assert.Equal(expect1, elem1.SomeProperty),
  elem2 => { 
     Assert.Equal(expect2, elem2.SomeProperty);
     Assert.True(elem2.TrueProperty);
  });

Ini menguji hitungan yang diharapkan dan memastikan bahwa setiap tindakan diverifikasi.

Drew Williams
sumber
2

Baru-baru ini, saya menggunakan xUnit 2.4.0danMoq 4.10.1 memaketkan aplikasi asp.net core 2.2 saya.

Dalam kasus saya, saya berhasil membuatnya berfungsi dengan dua langkah proses:

  1. Mendefinisikan implementasi dari IEqualityComparer<T>

  2. Teruskan instance pembanding sebagai parameter ketiga ke dalam Assert.Truemetode:

    Assert.True(expected, actual, new MyEqualityComparer());

Tetapi ada cara lain yang lebih bagus untuk mendapatkan hasil yang sama dengan menggunakan paket FluentAssertions . Ini memungkinkan Anda untuk melakukan hal berikut:

// Assert          
expected.Should().BeEquivalentTo(actual));

Menariknya, itu Assert.Equal()selalu gagal bahkan ketika saya memerintahkan elemen dua daftar untuk mendapatkannya dalam urutan yang sama.

Dmitry Stepanov
sumber
2
ada yang salah dengan pemesanan BeEquivalentTo Anda tidak peduli tentang pesanan (itulah mengapa tes Anda lolos dengan BeEquivalentTo dan bukan dengan assert.Equal)
RagnaRock