本The Art of Unit Testingでは、保守可能で読みやすい単体テストを作成したいということが述べられています。204 ページあたりで、1 つのテストで複数のアサートを避けるようにし、オーバーライドされた Equals メソッドでオブジェクトを比較する必要があると述べています。これは、期待される結果と実際の結果を比較するオブジェクトが 1 つしかない場合にうまく機能します。しかし、上記のオブジェクトのリスト (またはコレクション) がある場合はどうでしょう。
以下のテストを検討してください。複数の主張があります。実際、アサートを呼び出す 2 つの別個のループがあります。この場合、アサーションは 5 つになります。1 つのリストの内容が別のリストに存在することを確認する 2 と、その逆の 2 です。リスト内の要素の数を比較する 5 番目。
このテストを改善するための提案があれば、私はすべて耳にします。現在は MSTest を使用していますが、MSTest の Assert を流暢な API (Assert.That) 用の NUnits に置き換えました。
現在のリファクタリングされたコード:
[TestMethod]
#if !NUNIT
[HostType("Moles")]
#else
[Moled]
#endif
public void LoadCSVBillOfMaterials_WithCorrectCSVFile_ReturnsListOfCSVBillOfMaterialsThatMatchesInput()
{
//arrange object(s)
var filePath = "Path Does Not Matter Because of Mole in File object";
string[] csvDataCorrectlyFormatted = { "1000, 1, Alt 1, , TBD, 1, 10.0, Notes, , Description, 2.50, ,A",
"1001, 1, Alt 2, , TBD, 1, 10.0, Notes, , Description, 2.50, ,A" };
var materialsExpected = new List<CSVMaterial>();
materialsExpected.Add(new CSVMaterial("1000", 1, "Alt 1", "TBD", 1m, 10.0m, "Notes", "Description", 2.50m,"A"));
materialsExpected.Add(new CSVMaterial("1001", 1, "Alt 2", "TBD", 1m, 10.0m, "Notes", "Description", 2.50m,"A"));
//by-pass actually hitting the file system and use in-memory representation of CSV file
MFile.ReadAllLinesString = s => csvDataCorrectlyFormatted;
//act on object(s)
var materialsActual = modCSVImport.LoadCSVBillOfMaterials(filePath);
//assert something happended
Assert.That(materialsActual.Count,Is.EqualTo(materialsExpected.Count));
materialsExpected.ForEach((anExpectedMaterial) => Assert.That(materialsActual.Contains(anExpectedMaterial)));
materialsActual.ForEach((anActualMaterial) => Assert.That(materialsExpected.Contains(anActualMaterial)));
}
元のマルチアサート単体テスト:
...
//1st element
Assert.AreEqual("1000", materials[0].PartNumber);
Assert.AreEqual(1, materials[0].SequentialItemNumber);
Assert.AreEqual("Alt 1", materials[0].AltPartNumber);
Assert.AreEqual("TBD", materials[0].VendorCode);
Assert.AreEqual(1m, materials[0].Quantity);
Assert.AreEqual(10.0m, materials[0].PartWeight);
Assert.AreEqual("Notes", materials[0].PartNotes);
Assert.AreEqual("Description", materials[0].PartDescription);
Assert.AreEqual(2.50m, materials[0].UnitCost);
Assert.AreEqual("A", materials[1].Revision);
//2nd element
Assert.AreEqual("1001", materials[1].PartNumber);
Assert.AreEqual(1, materials[1].SequentialItemNumber);
Assert.AreEqual("Alt 2", materials[1].AltPartNumber);
Assert.AreEqual("TBD", materials[1].VendorCode);
Assert.AreEqual(1m, materials[1].Quantity);
Assert.AreEqual(10.0m, materials[1].PartWeight);
Assert.AreEqual("Notes", materials[1].PartNotes);
Assert.AreEqual("Description", materials[1].PartDescription);
Assert.AreEqual(2.50m, materials[1].UnitCost);
Assert.AreEqual("A", materials[1].Revision);
}