Les méthodes permettant d'Ajouter des Données pour se Moquer de bases de données en C# Tests Unitaires

Ce post est destiné à être davantage une discussion-démarreur, comme je suis un peu nouveau pour les tests unitaires et TDD.

Je suis présentement à l'écriture de tests unitaires pour une .NET processus qui interagit avec plusieurs bases de données, et suis en utilisant la maquette de la base de données des contextes dans une tentative de couvrir les différents cas de bord à l'intérieur de mes tests, vérifier la gestion des exceptions dans le programme lui-même, entre autres choses. Cela étant dit, certains de mes tests unitaires utilisation des données valides, tandis que d'autres ne le font pas.

Je suis à la recherche de commentaires, en termes de meilleures pratiques lors de l'ajout d'valide/faux les données de votre maquette de la base de données des contextes. J'ai vu des gens faire un certain nombre de façons (ex - mettre en œuvre un modèle de référentiel, l'ajout de se moquer de données .les fichiers csv et de les rendre le cadre du projet, etc...).

Je suis actuellement une réflexion sur l'utilisation d'un modèle de référentiel pour l'ajout de Survey objets à la Surveys table dans ma cible DB.

Tout d'abord, j'ai l'interface:

public interface ISurveyRepository
{
   IQueryable<Survey> SurveySeries { get; }
}

Ceci est mis en œuvre à la fois pour les moqueries faux/valide référentiels de données en tant que de besoin par les tests unitaires

class FakeSurveyRepository : ISurveyRepository
{
   private static IQueryable<Survey> fakeSurveySeries = new List<Survey> {
      new Survey { id = 1, SurveyName="NotValid1", SurveyData="<data>fake</data>"},
      new Survey { id = 2, SurveyName="NotValid2", SurveyData="<data>super fake</data>"},
      .........,
      new Survey {id = 10, SurveyName="NotValid10", SurveyData="<data>the fakest</data>" }       
   }.AsQueryable();

   public IQueryable<Survey> SurveySeries 
   { 
      get { return fakeSurveySeries; }
   }
}
//RealSurveyRepository : ISurveyRepository is similar to this, but with "good" data

J'ai ensuite une classe à utiliser ces données pour soit faux/données valides en étant passé à une référence à la série dans le constructeur:

public class SurveySeriesProcessor
{
   private ISurveyRepository surveyRepository;

   public SurveySeriesProcessor( ISurveyRepository surveyRepository )
   {
       this.surveyRepository = surveyRepository;
   }

   public IQueryable<Survey> GetSurveys()
   {
      return surveyRepository.SurveySeries
   }
} 

Et peut ensuite utiliser ces objets dans mes tests, tels que:

[TestClass]
public class SurveyTests
{
    [TestMethod]
    WhenInvalidSurveysFound_SurveyCopierThrowsInvalidSurveyDataErrorForEach()
    {
       //create mocking DB context and add fake data
       var contextFactory = new ContextFactory( ContextType.Mocking );
       var surveySeriesProcessor = new SurveySeriesProcessor( new FakeSurveyRepository() );

       foreach(Survey surveyRecord in surveySeriesProcessor.GetSurveys() )
       {
          contextFactory.TargetDBContext.Surveys.AddObject( surveyRecord );
       }
       //instantiate object being tested and run it against fake test data
       var testSurveyCopier = new SurveyCopier( contextFactory );
       testSurveyCopier.Start();
       //test behavior
       List<ErrorMessage> errors = testSurveyCopier.ErrorMessages;
       errors.Count.ShouldEqual( surveySeriesProcessor.GetSurveys().Count );
       foreach(ErrorMessage errMsg in errors)
       {
          errMsg.ErrorCode.ShouldEqual(ErrorMessage.ErrorMessageCode.InvalidSurveyData);
       }
    }
}

NOTE: je me rends compte que, dans l'exemple de code fourni je n'ai pas forcément besoin de faire les classes de la mise en œuvre de ISurveyRepository retour de la série comme un IQueryable<Survey> (ils pourraient très bien être List<Survey>). Cependant, je vais étendre les fonctionnalités de l'interface et de ces classes dans l'avenir pour filtrer les faux/valides des séries sur certains critères ajoutés à des requêtes LINQ, c'est pourquoi j'ai fait les référentiels de mettre en œuvre IQueryable<>. C'est de la maquette du code conçu pour transmettre les principes de base de ce que je pense.

Avec tout cela à l'esprit, ce que je vous pose est:

  1. Avez-vous des suggestions en ce qui concerne d'autres approches que je pouvais prendre dans de tels scénarios?
  2. Quelles sont les méthodes que vous avez employées dans le passé, qu'avez-vous aimé/pas comme eux? Qui avez-vous trouvé le plus facile à maintenir?
  3. Compte tenu de ce que j'ai posté, avez-vous remarqué des défauts dans mon approche générale de l'unité de test? Parfois j'ai l'impression d'écrire des tests unitaires qui tentent de couvrir trop de terrain au lieu d'être concis, élégant, et à-le-point.

C'est censé être un peu d'une discussion ouverte. Veuillez garder à l'esprit, c'est la première série de tests unitaires que j'ai jamais écrit (j'ai lu une quantité décente de la littérature sur le sujet, cependant).