Je vais avoir une bibliothèque de classes, elle contient le modèle et la méthode suivants
Modèle:
public class Employee {
public int EmpId { get; set; }
public string Name { get; set; }
}
Méthode:
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();
}
}
J'ai une méthode de test
[TestMethod()]
public void GetEmployeeTest() {
EmployeeService obj = new EmployeeService();
var result = obj.GetEmployee();
Xunit.Assert.Collection<Employee>(result, m => Xunit.Assert.Contains("John",m.Name));
}
J'ai reçu un message d'exception
Assert.Collection() Failure
Collection: [Employee { EmpId = 1, Name = "John" }, Employee { EmpId = 2, Name = "Albert John" }]
Expected item count: 1
Actual item count: 2
Mon exigence est de vérifier que tous les items.Name
doivent contenir la sous-chaîne "John". Veuillez m'aider à vérifier avec Xunit.Assert.Collection
Il semble qu'Assert.Collection utilise uniquement chaque inspecteur d'élément. Donc, pour votre test, les travaux suivants:
[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));
}
Mais cela signifie que result
doit avoir exactement deux éléments.
Changer la Assert
en
Assert.All(result, item => Assert.Contains("John", item.Name));
devrait vous donner le résultat que vous attendez.
Ceci est une extension de answer de Ayb4btu pour ceux qui ne sont pas intéressés par l’ordre des éléments de la collection.
La méthode suivante est basée sur l'implémentation XUnit d'origine et vous permettra de tester en utilisant une interface très similaire:
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);
}
}
}
}
La différence ici est que pour une collection
string[] collectionToTest = { "Bob", "Kate" };
Les deux lignes suivantes ne produiront pas de CollectionException
TestExpect.CollectionContainsOnlyExpectedElements(collectionToTest, x => x.Equals("Bob"), x => x.Equals("Kate"));
TestExpect.CollectionContainsOnlyExpectedElements(collectionToTest, x => x.Equals("Kate"), x => x.Equals("Bob"));
Considérant que l’utilisation de Assert.Collection
- Seule la première des deux lignes ci-dessus fonctionnera lorsque la collection d’inspecteurs est évaluée dans l’ordre.
Cette méthode présente un impact potentiel sur les performances, mais si vous testez uniquement des collections de taille relativement petite (comme vous le ferez probablement dans un test unitaire), vous ne remarquerez jamais la différence.