Pertanyaan KoleksiMasukkan menggunakan generik?


Sepertinya CollectionAssert tidak bisa digunakan dengan obat generik. Ini sangat membuat frustasi; kode yang ingin saya uji tidak menggunakan generik. Apa yang harus saya lakukan? Tulis boilerplate untuk mengkonversi antara keduanya? Memeriksa kesetaraan koleksi secara manual?

Ini gagal:

ICollection<IDictionary<string, string>> expected = // ...

IEnumerable<IDictionary<string, string>> actual = // ...

// error 1 and 2 here
CollectionAssert.AreEqual(expected.GetEnumerator().ToList(), actual.ToList());

// error 3 here
Assert.IsTrue(expected.GetEnumerator().SequenceEquals(actual));

Kesalahan kompiler:

Galat 1:

'System.Collections.Generic.IEnumerator>' tidak berisi definisi untuk 'ToList' dan tidak ada metode ekstensi 'ToList' yang menerima argumen pertama tipe 'System.Collections.Generic.IEnumerator>' dapat ditemukan

Galat 2

'System.Collections.Generic.IEnumerator>' tidak berisi definisi untuk 'ToList' dan tidak ada metode ekstensi 'ToList' yang menerima argumen pertama tipe 'System.Collections.Generic.IEnumerator>' dapat ditemukan

Galat 3

'System.Collections.Generic.IEnumerator>' tidak berisi definisi untuk 'SequenceEquals' dan tidak ada metode perluasan 'SequenceEquals' yang menerima argumen pertama tipe 'System.Collections.Generic.IEnumerator>' dapat ditemukan

Apa yang saya lakukan salah? Apakah saya tidak menggunakan ekstensi dengan benar?

Memperbarui: Ok, ini terlihat sedikit lebih baik, tetapi tetap tidak berfungsi:

IEnumerable<IDictionary<string, string>> expected = // ...

IEnumerable<IDictionary<string, string>> actual = // ...

CollectionAssert.AreEquivalent(expected.ToList(), actual.ToList()); // fails
CollectionAssert.IsSubsetOf(expected.ToList(), actual.ToList()); // fails

Saya tidak ingin membandingkan daftar; Saya hanya peduli tentang menetapkan kesetaraan keanggotaan. Urutan anggota tidak penting. Bagaimana saya bisa mengatasi ini?


32
2018-03-14 04:30


asal


Jawaban:


Kamu bisa gunakan CollectionAssert dengan koleksi generik. Triknya adalah memahami bahwa metode CollectionAssert beroperasi ICollection, dan meskipun beberapa antarmuka koleksi generik diterapkan ICollection, List<T> tidak.

Demikian, Anda dapat mengatasi keterbatasan ini dengan menggunakan ToList metode penyuluhan:

IEnumerable<Foo> expected = //...
IEnumerable<Foo> actual = //...
CollectionAssert.AreEqual(expected.ToList(), actual.ToList());

Yang mengatakan, saya masih menganggap CollectionAssert rusak dalam banyak cara lain, jadi saya cenderung menggunakan Assert.IsTrue dengan metode ekstensi LINQ, seperti ini:

Assert.IsTrue(expected.SequenceEquals(actual));

FWIW, saat ini saya menggunakan metode ekstensi ini untuk melakukan perbandingan lain:

public static class EnumerableExtension
{
    public static bool IsEquivalentTo(this IEnumerable first, IEnumerable second)
    {
        var secondList = second.Cast<object>().ToList();
        foreach (var item in first)
        {
            var index = secondList.FindIndex(item.Equals);
            if (index < 0)
            {
                return false;
            }
            secondList.RemoveAt(index);
        }
        return secondList.Count == 0;
    }

    public static bool IsSubsetOf(this IEnumerable first, IEnumerable second)
    {
        var secondList = second.Cast<object>().ToList();
        foreach (var item in first)
        {
            var index = secondList.FindIndex(item.Equals);
            if (index < 0)
            {
                return false;
            }
            secondList.RemoveAt(index);
        }
        return true;
    }
}

33
2018-03-14 07:06



Jika Anda bekerja dengan Sets, gunakan Idiom ini

HashSet<string> set1  = new HashSet<string>(){"A","B"};
HashSet<string> set2  = new HashSet<string>(){"B","A"};

Assert.IsTrue(set1.SetEquals(set2));

5
2018-05-20 09:32



Anda dapat dengan mudah menulis versi generik Anda sendiri, lalu memindahkannya ke kelas dasar atau utilitas yang digunakan dalam semua tes Anda. Basiskan pada operator LINQ seperti Semua dan Any.


1
2018-03-14 04:40