Pourquoi le bien que je veux pour se moquer besoin d'être virtuel?
Je suis en train de faire quelques tests unitaires, et se moquant de certaines propriétés à l'aide de Moq.
Maintenant, c'est un Contrôleur test (ASP.NET MVC 3). Mon Contrôleurs de dériver à partir d'un résumé contrôleur, nommé AbstractController.
Ce contrôleur a une dépendance sur le Contexte Http (pour faire des choses comme la thématisation, spécifique au domaine de la logique basée sur HTTP en-têtes d'HÔTE, etc).
Cela se fait via une propriété appelée WebSiteSettings:
public abstract class AbstractController : Controller
{
public WebSiteSettings WebSiteSettings { get; private set; }
//other code
}
Avis d'un ensemble privé - le ctor il établit. Donc, je l'ai changé pour utilisé une interface, et c'est ce que j'ai raillé:
public IWebSiteSettings WebSiteSettings { get; private set; }
Ensuite, j'ai créé un "FakeWebSiteSettings", qui se moque de la Http Contexte pour lire les en-têtes HTTP.
Le problème c'est que quand je lance le test, je reçois un NotSupportedException:
Non valide le programme d'installation sur un non-virtuel (substituables en VB) membre: x => x.WebSiteSettings
Voici pertinentes se moquant de code:
var mockWebSiteSettings = new Mock<FakeWebSiteSettings>();
var mockController = new Mock<MyController>(SomeRepository);
mockController.Setup(x => x.WebSiteSettings).Returns(mockWebSiteSettings.Object);
_controller = mockController.Object;
var httpContextBase = MvcMockHelpers.FakeHttpContext();
httpContextBase.Setup(x => x.Request.ServerVariables).Returns(new NameValueCollection
{
{"HTTP_HOST","localhost.www.mydomain.com"},
});
_controller.SetFakeControllerContext(httpContextBase.Object);
Si je fais le WebsiteSettings
propriété virtuel - le test passe.
Mais je ne comprends pas pourquoi j'ai besoin pour ce faire. Je ne suis pas vraiment primordial la propriété, je suis tout simplement en se moquant de la façon dont il est installé.
Suis-je raté quelque chose, ou de faire de ce mal?
Vous devez vous connecter pour publier un commentaire.
Moq et d'autres semblables, se moquant des cadres ne peut se moquer des interfaces, méthodes abstraites/propriétés (sur les classes abstraites) ou virtuel méthodes/propriétés sur les classes de béton.
C'est parce qu'il génère un proxy qui va implémenter l'interface ou de créer une classe dérivée qui remplace ceux remplacable méthodes afin d'intercepter les appels.
J'ai créé une interface et une classe wrapper. par exemple,
puis dans vos tests unitaires juste se moquer de l'interface:
Évidemment, vous pourriez avoir besoin d'inclure plus de propriétés /méthodes. Mais le truc.
Une autre astuce utile pour d'autres se moquant de problèmes, tels que la modification de la date actuelle heure (j'ai toujours utiliser UTC date heure):
par exemple, si vous avez un service qui s'exécute toutes les x minutes, vous pouvez juste se moquer de la IDateTimeProvider et le retour d'un temps plus tard, pour vérifier que le service est exécuté à nouveau... ou quoi que ce soit.
"Donc....ce que j'ai fait est le seul moyen?"
Non seulement vous êtes beaucoup mieux la mise en œuvre d'une interface et les moqueries que. Alors vos méthodes peuvent être virtuels ou pas, comme vous le choisissez.
Bien que, tout ce qui a été dit avant est vrai, il vaut la peine de savoir que le proxy-moqueur approche (comme celui qui moq utilise)je n'est pas la seule possible.
Vérifier http://www.typemock.com/ pour une approche globale, solution, qui permet de se moquer à la fois étanche classes, non-virtuelle, des méthodes, etc. Assez puissant.