Question

J'essaie de tester unitairement une classe comportant de nombreuses fonctions internes. Celles-ci doivent évidemment aussi être testées, mais mon projet de test est séparé, principalement parce qu’il couvre de nombreux petits projets connexes. Ce que j’ai jusqu’à présent, c’est:

FieldInfo[] _fields = 
    typeof(ButtonedForm.TitleButton).GetFields(
        BindingFlags.NonPublic | BindingFlags.Instance | 
        BindingFlags.DeclaredOnly);
Console.WriteLine("{0} fields:", _fields.Length);
foreach (FieldInfo fi in _fields)
{
    Console.WriteLine(fi.Name);
}

Ceci crache gentiment tous les membres privés, mais n’affiche toujours pas les éléments internes. Je sais que cela est possible, car lorsque je m'amusais avec les tests générés automatiquement que Visual Studio peut produire, il posait des questions sur l'affichage des éléments internes dans le projet Test. Maintenant, j'utilise NUnit et je l’aime vraiment beaucoup, mais comment puis-je obtenir le même résultat?

Était-ce utile?

La solution

Il serait plus approprié d'utiliser le InternalsVisibleTo autorisant l’accès aux membres internes de l’assembly à votre assembly de test unitaire.

Voici un lien contenant des informations supplémentaires utiles et une visite guidée:

Pour répondre réellement à votre question ... Interne et protégé ne sont pas reconnus dans l'API .NET Reflection. Voici une citation de MSDN :

  

Les mots clés C # protégés et internes n'ont aucune signification en IL et ne sont pas utilisés dans les API de Reflection. Les termes correspondants en IL sont Famille et Assemblée. Pour identifier une méthode interne à l'aide de Reflection, utilisez la IsAssembly propriété. Pour identifier une méthode interne protégée, utilisez IsFamilyOrAssembly .

Autres conseils

Ajout de attribut InternalsVisibleTo votre projet principal, avec le nom de l’assemblée thre test project, doit rendre les membres internes visibles.

Par exemple, ajoutez les éléments suivants à votre assemblage en dehors de toute classe:

[assembly: InternalsVisibleTo("AssemblyB")]

Ou pour un ciblage plus spécifique:

[assembly:InternalsVisibleTo("AssemblyB, PublicKey=32ab4ba45e0a69a1")]

Notez que si l'assembly de votre application porte un nom fort, votre assemblage de test devra également porter un nom fort.

Je pense que vous devez vous demander si vous devez écrire des tests unitaires pour les méthodes privées. Si vous écrivez des tests unitaires pour vos méthodes publiques, avec une couverture de code "raisonnable", ne testez-vous pas déjà des méthodes privées qui doivent être appelées à la suite?

Lier les tests à des méthodes privées rendra les tests plus fragiles. Vous devriez pouvoir modifier l’implémentation de toute méthode privée sans interrompre aucun test.

Réf.:

http://weblogs.asp.net/tgraham/ archive / 2003/12/31 / 46984.aspx http://richardsbraindump.blogspot.com/2008 /08/should-i-unit-test-private-methods.html http://junit.sourceforge.net/doc/faq/faq.htm#tests_11 http://geekswithblogs.net/geekusconlivus/archive/2006/07/13 /85088.aspx

Votre code n’affiche que les champs. J’espère donc qu’il ne montrera aucun membre interne, car les champs doivent toujours être OMI privé. (À l’exception potentielle des constantes.)

ButtonedForm.TitleButton a-t-il réellement des champs non privés? Si vous essayez de trouver des méthodes internes, vous devez évidemment appeler GetMethods (ou GetMembers ) pour les obtenir.

Comme d'autres l'ont suggéré, InternalsVisibleTo est très pratique pour les tests (et presque uniquement pour les tests!). Pour ce qui est de savoir si vous devriez tester des méthodes internes - je trouve certainement utile de pouvoir le faire. Je ne considère pas les tests unitaires comme des tests exclusivement en boîte noire. Souvent, lorsque vous savez que la fonctionnalité publique est implémentée à l’aide de quelques méthodes internes connectées de manière simple, il est plus facile de tester minutieusement chacune des méthodes internes et certains "pseudo-intégrations". tests sur la méthode publique.

Une justification pour utiliser InternalsVisible se trouve dans mes circonstances. Nous achetons le code source à un contrôle graphique. Nous avons trouvé où nous devons apporter quelques modifications à ce contrôle de code source et compiler notre propre version. Maintenant, pour nous assurer de ne rien casser, il me faut écrire certains tests unitaires nécessitant un accès à certains champs internes.

C’est un cas parfait où l’InternalsVisible prend tout son sens.

Je me demandais cependant que faites-vous si vous n’avez pas accès à la source? Comment pouvez-vous accéder à un champ interne? .Net Reflector peut voir ce code, mais j’imagine qu’il ne fait que regarder le IL.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top