2010-06-04 4 views
2

J'ai étudié comment découpler mes DomainServices de leur source de données afin que je puisse les tester dans des tests unitaires. Je commence à penser que les découpler complètement n'est pas possible.Mocking ObjectContext, traitant de la méthode ObjectQuery.Include (string)?

Il ya une quantité décente d'informations là-bas, comme ce question et ce blog post. Le blog, en particulier, vous amène vraiment loin en se moquant d'ObjectContext.

Mais mes DomainServices ont des méthodes comme celle-ci:

public IQueryable<Client> GetClients() 
{ 
    return ObjectContext.Clients 
     .Include("Foo") 
     .Include("Bar") 
     .Where(c => c.IsBaz); 
} 

Il ne semble pas possible de se moquer complètement la méthode Include, car il renvoie un ObjectQuery<T>, et la méthode Inclure est pas pris dans une interface nulle part (Il n'y a pas d'interface IObjectQuery). ObjectQuery implémente IQueryable<T>, et donc je pensais faire ma propre méthode d'inclusion qui renvoie IQueryable fonctionnerait, mais seulement si je prévois d'appeler au plus une fois par requête. J'utilise EF4, .NET 4, Silverlight 4 et RIA Services RTW.

un peu comme une diatribe, je suis déçu de voir comment tester LINQ hostile aux entités et par extension RIA Services est :(

Répondre

1

Je ne pense pas que vous devriez être les tests unitaires à ce niveau. I » m pour les tests unitaires, mais il y a un certain point où vous devez vous arrêter

Disons que le code fait partie d'un clientLinqRepository, qui implémente à son tour IClientsLinqRepository, lorsque vous implémentez le code qui dépend de

Bien que ce qui précède soit parfaitement valide, ClientsLinqRepository est un outil d'intégration ation. Un peu comme si vous aviez IMessageSender et que vous avez implémenté MailSender. Ici vous avez du code que sa principale responsabilité est l'intégration avec un système séparé, pour vous c'est la base de données.

Basé sur le scénario ci-dessus, je suggère que vous fassiez quelques tests d'intégration concentrée sur cette classe. Donc, dans ce cas, vous voulez frapper le système externe (base de données), et assurez-vous que le code d'intégration fonctionne correctement avec le système externe. Cela vous permettra d'identifier rapidement si quelque chose dans le code par rapport à la base de données est cassé sans traiter de la complexité du reste du système (ce qui est pénible lorsqu'on essaie de faire des tests d'intégration à d'autres niveaux). Conservez les tests d'intégration ciblés séparément des tests unitaires, afin de pouvoir exécuter les tests unitaires incroyablement rapidement autant que vous le souhaitez et effectuez un test d'intégration lorsque des modifications sont apportées à l'une des pièces d'intégration et de temps en temps.

+0

Ouais faire ces tests d'intégration au lieu de tests unitaires est une solution et probablement celle que je vais suivre. Bien que je me sens comme c'est un peu un flic. Mon DomainService a des méthodes que je veux tester, c'est une demande valide. C'est une partie réelle de l'application, car elle décide quelles données à la surface. Sans parler de moquer DomainServices pour les tests unitaires est un sujet assez commun, c'est juste la plupart des exemples qui utilisent LINQ to SQL parce que c'est plus facile de se moquer. –

+0

J'ai raté que c'était sur votre DomainService. Honnêtement, je ne connais pas très bien les termes DDD, mais la recherche d'objets dans la base de données ne ressemble pas à un service de domaine, les gens appellent le service beaucoup de choses différentes (dans DDD ou non). Je regarderais de cette façon: avez-vous mélangé la responsabilité de l'extraction d'objet/intégration de base de données avec d'autres logique ces services de domaine font? C'est peut-être le code qui vous demande de retirer une responsabilité.Vous aurez à tester la logique réelle dans vos tests unitaires, et l'intégration réelle dans les tests d'intégration ciblés. – eglasius

+0

DomainService est le point de terminaison que le client appelle pour extraire des données. Mais il ne fait pas de récupération de données réelles, il est généralement donné un objet pour faire la récupération de données réelle (Dans le cas d'un DomainService qui étend 'LinqToEntitiesDomainService', il demande à ObjectContext d'aller extraire les données de la base de données en utilisant LINQ to Entities). ObjectContext est ce que je veux mocker, donc je peux donner les données de faux DomainService pendant le test ... –