web-dev-qa-db-fra.com

Problèmes dans Xunit.Assert.Collection - C #

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

6
user7784919

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.

19
Ayb4btu

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.

0
Jay