Ich habe eine Klassenbibliothek. Sie enthält das folgende Modell und die Methode
Modell:
public class Employee {
public int EmpId { get; set; }
public string Name { get; set; }
}
Methode:
public class EmployeeService {
public List<Employee> GetEmployee() {
return new List<Employee>() {
new Employee() { EmpId = 1, Name = "John" },
new Employee() { EmpId = 2, Name = "Albert John" },
new Employee() { EmpId = 3, Name = "Emma" },
}.Where(m => m.Name.Contains("John")).ToList();
}
}
Ich habe eine Testmethode
[TestMethod()]
public void GetEmployeeTest() {
EmployeeService obj = new EmployeeService();
var result = obj.GetEmployee();
Xunit.Assert.Collection<Employee>(result, m => Xunit.Assert.Contains("John",m.Name));
}
Ich habe eine Ausnahmemeldung erhalten
Assert.Collection() Failure
Collection: [Employee { EmpId = 1, Name = "John" }, Employee { EmpId = 2, Name = "Albert John" }]
Expected item count: 1
Actual item count: 2
Meine Anforderung ist zu prüfen, ob der items.Name
die Unterzeichenfolge "John" enthält. Helfen Sie mir bitte mit Xunit.Assert.Collection
zu überprüfen
Es scheint, dass Assert.Collection jeden Elementinspektor nur einmal verwendet. Für Ihren Test funktionieren also die folgenden:
[Fact]
public void GetEmployeeTest()
{
EmployeeService obj = new EmployeeService();
var result = obj.GetEmployee();
Assert.Collection(result, item => Assert.Contains("John", item.Name),
item => Assert.Contains("John", item.Name));
}
Dies bedeutet jedoch, dass result
genau zwei Elemente haben muss.
Assert
in ändern
Assert.All(result, item => Assert.Contains("John", item.Name));
sollte Ihnen das Ergebnis geben, das Sie erwarten.
Dies ist eine Erweiterung von Ayb4btus answer für diejenigen, die sich nicht für die Reihenfolge der Elemente in der Sammlung interessieren.
Die folgende Methode basiert auf der ursprünglichen XUnit-Implementierung und ermöglicht das Testen mit einer sehr ähnlichen Schnittstelle:
public static class TestExpect
{
public static void CollectionContainsOnlyExpectedElements<T>(IEnumerable<T> collectionToTest, params Func<T, bool>[] inspectors)
{
int expectedLength = inspectors.Length;
T[] actual = collectionToTest.ToArray();
int actualLength = actual.Length;
if (actualLength != expectedLength)
throw new CollectionException(collectionToTest, expectedLength, actualLength);
List<Func<T, bool>> allInspectors = new List<Func<T, bool>>(inspectors);
int index = -1;
foreach (T elementToTest in actual)
{
try
{
index++;
Func<T, bool> elementInspectorToRemove = null;
foreach (Func<T, bool> elementInspector in allInspectors)
{
if (elementInspector.Invoke(elementToTest))
{
elementInspectorToRemove = elementInspector;
break;
}
}
if (elementInspectorToRemove != null)
allInspectors.Remove(elementInspectorToRemove);
else
throw new CollectionException(collectionToTest, expectedLength, actualLength, index);
}
catch (Exception ex)
{
throw new CollectionException(collectionToTest, expectedLength, actualLength, index, ex);
}
}
}
}
Der Unterschied hier ist der für eine Sammlung
string[] collectionToTest = { "Bob", "Kate" };
Die beiden folgenden Zeilen erzeugen keine CollectionException
TestExpect.CollectionContainsOnlyExpectedElements(collectionToTest, x => x.Equals("Bob"), x => x.Equals("Kate"));
TestExpect.CollectionContainsOnlyExpectedElements(collectionToTest, x => x.Equals("Kate"), x => x.Equals("Bob"));
Während Assert.Collection
verwendet wird, funktioniert nur die erste der beiden obigen Zeilen, da die Sammlung der Inspektoren der Reihe nach ausgewertet wird.
Mit dieser Methode kann die Leistung beeinträchtigt werden. Wenn Sie jedoch nur relativ kleine Sammlungen testen (wie Sie wahrscheinlich in einem Komponententest sind), werden Sie den Unterschied nie bemerken.