2009-09-10 6 views
0

Je suis unité test code qui interactes avec un référentiel, qui prend une expression (Expression<Func<Entity, bool>>) pour filtrer les résultats, comme ceci:Test d'unité avec des expressions?

int orderId = 10; 

_respository.GetFiltered(order => order.Id == orderId); 

J'ai un problème unité d'essai, plus la mise spécifiquement des attentes une expression correspondra. Lors d'un test de l'unité que je veux faire ceci:

_mockRespository.Setup(r => r.GetFiltered(order => order.Id == 10)).Returns(new Order[0]).AtMostOnce(); 

J'ai trouvé une solution qui a suggéré de faire .ToString() chaque expression et compairing que, toutefois, lorsque vous faites référence à une variable telle que orderId, l'expression est complètement différent!

Que font les gens pour tester cela?

Merci,

David

+0

Je ne suis pas sûr de comprendre ... au lieu de passer des expressions à la méthode d'installation. Que faire si vous le mettez en cache dans une variable locale et que vous le transmettez à la méthode d'installation. – Gishu

+0

Si vous faites cela, alors la même question demeure! Comment puis-je comparer que deux expressions sont les mêmes? –

Répondre

0

Je dirais que cela est en partie une question de ce que vous voulez vraiment vérifier avec un test unitaire, ce qui revient à votre philosophie de tests unitaires. Ce que nous faisons est que nous ne vérifions pas nécessairement qu'un paramètre d'expression linq to entities passé du type A (sous test) utilise une arborescence d'expression spécifique lors de l'appel de GetFoo() sur un collaborateur de référentiel (non testé). Pour un test unitaire, nous nous contentons de vérifier que la méthode GetFoo() la bonne signature est appelée du tout.

Dans votre cas, il semble que vous utilisez Moq (?), Auquel cas qui deviendrait quelque chose comme ça (méfiez-vous de mess syntaxe)

_mockRespository.Setup(r => r.GetFiltered(It.IsAny<Expression<Func<Entity, bool>>>())).Returns(new Order[0]).AtMostOnce(); 

Pour nous, cela a du sens parce que a) raillé b) bien que nous puissions vérifier ce paramètre, comment B interpréterait différentes combinaisons de valeurs de paramètres pourrait changer (comme dans la sémantique du contrat A-> B) et si c'est le cas, rendrait le test cassant. Nous utilisons des tests d'histoire automatisés pour tester l'interaction entre la production A et la production B. Nous pensons que c'est une meilleure façon de tester ces scénarios, car ils sont typiquement quelque chose comme "filtrer tout A en stockage selon l'expression X et me donner tous les objets qui correspondent ". Pour nous, cela a du sens en tant que tests d'intégration (un ou deux cas heureux suffisent habituellement). Si cela ne vous suffit pas, je vous dirais: a) comment créer des personnalisateurs Moq personnalisés, bien que je ne puisse pas dire avec certitude qu'il existe une solution facile (il pourrait très bien y en avoir) ou b) la configuration des rappels d'attente afin que vous puissiez capturer le paramètre et l'inspecter après le test. Quelque chose comme ceci:

Expression<Func<Entity, bool>> actualExpression = null; 
    _mockRespository.Setup(r => r.GetFiltered(It.IsAny<Expression<Func<Entity, bool>>>())).Returns(new Order[0]).AtMostOnce().Callback((Expression<Func<Entity, bool>> expr => { actualExpression = expr}); 

    // exercise production code 

    Assert.IsTrue(actualExpression ...... someithing clever here); 

Remarque: Tout le code ci-dessus a été écrit dans l'éditeur de débordement de pile. Ne me tenez pas responsable si elle ne compile pas, les docs Moq couvrent cela

Questions connexes