2010-08-18 9 views
1

J'essaie d'écrire des tests pour une application MVC que nous sommes en train de développer. Nous avons une classe BaseController qui contient les éléments suivants:MSTest, accesseurs, héritage et membres privés

public class BaseController : Controller 
{ 
    protected string UserRole { get; private set; } 

Nous avons alors un contrôleur qui hérite de la BaseController:

public class CustomFieldController : BaseController 

J'ai produit accesseurs privé pour les deux classes (il suffit de les régénérer quelques il y a quelques minutes). Dans l'un de mes tests unitaires pour CustomFieldController Je veux régler le UserRole, donc j'ai le code suivant:

CustomFieldController controller = new CustomFieldController(); 
CustomFieldController_Accessor accessor = new CustomFieldController_Accessor( 
    new PrivateObject(controller, new PrivateType(typeof(BaseController)))); 

accessor.UserRole = "OTHER"; 

Chaque fois que je tente de lancer ce test, il lance une exception sur la dernière ligne indiquant:

Le membre spécifié (CustomFieldEdit) est introuvable. Vous devrez peut-être régénérer votre accesseur privé, ou le membre peut être privé et défini sur une classe de base. Si ce dernier est vrai, vous devez passer le type qui définit le membre dans le constructeur PrivateObject.

Pour autant que je sache, j'ai fait ce qu'il dit. Non seulement j'ai récemment régénéré l'accesseur privé, mais je passe le type qui définit le membre dans le constructeur de PrivateObject.

Des pensées sur ce qui me manque ici? Je sais que je peux le faire en supprimant le "private" du setter de la propriété, mais je ne le ferais pas si je peux l'éviter (je ne veux pas que les implémenteurs de sous-classes pensent pouvoir injecter une valeur dans cette propriété).

+0

Il suffit de ne pas utiliser ces trucs accesseur privé - vous fait écrire que le code des ordures. Vous ne devez tester que l'unité publique de votre classe. – Grzenio

+3

Peut-être que mon message n'était pas clair. Je n'essaie pas de tester la propriété (ce serait plutôt stupide). Afin de tester tous les chemins de code d'un couple des méthodes que cette propriété a besoin d'avoir une valeur. Je suis également en désaccord sur le fait que seule l'interface publique devrait être testée. Les méthodes privées forment souvent la base de l'interface publique, et le fait de pouvoir tester ces unités de travail plus petites pour s'assurer qu'elles font toutes leur travail correctement me semble correspondre exactement à ce que les tests unitaires ont à voir. –

Répondre

4

CustomFieldController controller = new CustomFieldController();
var po = new PrivateObject(controller, new PrivateType(typeof(BaseController)));
CustomFieldController_Accessor accessor = new CustomFieldController_Accessor(po);

po.SetFieldOrProperty("UserRole","OTHER"); 

+0

C'est ce qu'il a fait. Merci. –

+0

Bien que cela résout le problème et que je comprenne pourquoi il l'a corrigé (le PrivateType doit être ajouté pour que l'Accesseur sache quel objet rechercher les membres lors de l'exécution), puis-je suggérer une brève explication? utilisateurs? – bsara