2017-09-17 99 views
2

我想創建一個單元測試,比較兩個字符串數組列表。比較兩個列表中的<string[]>對象在C#單元測試

我試圖創建兩個完全相同的List<string[]>的對象,但是當我使用CollectionAssert.AreEqual(expected, actual);,該測試失敗:

[TestMethod] 
public void TestList() 
{ 
    List<string[]> expected = new List<string[]> { 
     new string[] { "John", "Smith", "200" }, 
     new string[] { "John", "Doe", "-100" } 
    }; 

    List<string[]> actual = new List<string[]> { 
     new string[] { "John", "Smith", "200" }, 
     new string[] { "John", "Doe", "-100" } 
    }; 

    CollectionAssert.AreEqual(expected, actual); 
} 

我也試過Assert.IsTrue(expected.SequenceEqual(actual));,但失敗也是如此。

如果我比較兩個字符串列表或兩個字符串數組,但它們在比較兩個字符串數組列表時無效。

我假設這些方法失敗,因爲他們比較兩個對象引用列表而不是數組字符串值。

如何比較兩個List<string[]>對象並判斷它們是否真的相同?

+2

試試這個:元素,你可以當你把它做到這一點通過在IComparer'expected.Zip(實際,(E,A)=> e.SequenceEqual(一))所有( x => x)'。 – Enigmativity

+0

出於好奇......如果它們具有相同的元素但順序不同,您會認爲列表「相等」嗎?另外,值得注意的是,一個字符串數組是一個對象的可怕替代品。 – David

+0

@David對於這個特定的測試,我會很好的解決方案,要求元素的順序相同,以及忽略順序的解決方案。我同意對象通常比字符串數組更好。此代碼是更大圖片的一部分,需要採用此格式。 –

回答

3

這是失敗,因爲在清單中的項目是對象(string[]),並因爲你沒有指定如何CollectionAssert.AreEqual應該比較它回落到是比較引用的默認行爲的兩個序列的元素。如果你要改變你的名單如下,例如,你會發現,測試通過,因爲現在這兩個列表都引用同一個數組:

var first = new string[] { "John", "Smith", "200" }; 
var second = new string[] { "John", "Smith", "200" }; 

List<string[]> expected = new List<string[]> { first, second}; 
List<string[]> actual = new List<string[]> { first, second}; 

以避免破壞參照比較,你需要告訴CollectionAssert.AreEqual如何比較

CollectionAssert.AreEqual(expected, actual, StructuralComparisons.StructuralComparer); 
4

CollectionAssert.AreEqual(expected, actual);失敗,因爲它比較對象引用。 expectedactual指的是不同的對象。

Assert.IsTrue(expected.SequenceEqual(actual));因相同原因失敗。這一次的內容expectedactual進行了比較,但元素本身是不同的數組引用。

也許嘗試使用SelectMany拉平兩個序列:

var expectedSequence = expected.SelectMany(x => x).ToList(); 
var actualSequence = actual.SelectMany(x => x).ToList(); 
CollectionAssert.AreEqual(expectedSequence, actualSequence); 

由於Enigmativity在他的評論正確地注意到,的SelectMany可以給予了積極的結果,當陣列數量和/或它們的元素是不同的,但展平列表將導致相同數量的元素。只有在這些陣列中始終具有相同數量的數組和元素的情況下才是安全的。

+0

你已經釘了它,與對象引用的解釋,但'.SelectMany'方法創建了一大堆「誤報」,並且不需要'.Select(y => y)' – Enigmativity

+0

感謝評論。我錯過了。我編輯了我的帖子。 – Kapol

0

最好的解決方案是檢查每個子集合中的項目以及每個子集合中項目的數量。

試試這個:

bool equals = expected.Count == actual.Count && 
       Enumerable.Range(0, expected.Count).All(i => expected[i].Length == actual[i].Length && 
                  expected[i].SequenceEqual(actual[i])); 
Assert.IsTrue(equals); 

這將檢查:

  • 兩個列表具有相同的長度
  • 所有都列出了一子集的具有相同的長度
  • 每副子集中的物品都是一樣的

注意:使用SelectMany不是一個好主意,因爲它可能會產生誤報,您在第二個列表中有相同的項目,但分散在不同的子集合中。我的意思是,即使第二個在一個子集合中有相同的項目,它也會考慮兩個列表是相同的。