visual - unit test c#




Comment les gens font-ils des tests unitaires avec Entity Framework 6? (7)

C'est un sujet qui m'intéresse beaucoup. Il y a beaucoup de puristes qui disent que vous ne devriez pas tester des technologies comme EF et NHibernate. Ils ont raison, ils sont déjà très rigoureusement testés et comme une réponse précédente, il est souvent inutile de passer beaucoup de temps à tester ce que vous ne possédez pas.

Cependant, vous possédez la base de données en dessous! C'est là que cette approche se décompose, vous n'avez pas besoin de tester que EF / NH font leur travail correctement. Vous devez tester que vos mappings / implémentations fonctionnent avec votre base de données. À mon avis, c'est l'une des parties les plus importantes d'un système que vous pouvez tester.

Strictement parlant cependant, nous passons du domaine des tests unitaires et des tests d'intégration, mais les principes restent les mêmes.

La première chose que vous devez faire est de pouvoir se moquer de votre DAL afin que votre BLL puisse être testé indépendamment de EF et de SQL. Ce sont vos tests unitaires. Ensuite, vous devez concevoir vos tests d'intégration pour prouver votre DAL, à mon avis, ceux-ci sont tout aussi importants.

Il y a deux choses à considérer:

  1. Votre base de données doit être dans un état connu avec chaque test. La plupart des systèmes utilisent une sauvegarde ou créent des scripts pour cela.
  2. Chaque test doit être répétable
  3. Chaque test doit être atomique

Il existe deux approches principales pour configurer votre base de données, la première consiste à exécuter un script DB UnitTest create. Cela garantit que votre base de données de tests unitaires sera toujours dans le même état au début de chaque test (vous pouvez soit réinitialiser ceci ou exécuter chaque test dans une transaction pour assurer cela).

Votre autre option est ce que je fais, exécuter des configurations spécifiques pour chaque test individuel. Je crois que c'est la meilleure approche pour deux raisons principales:

  • Votre base de données est plus simple, vous n'avez pas besoin d'un schéma complet pour chaque test
  • Chaque test est plus sûr, si vous modifiez une valeur dans votre script de création, cela n'invalide pas des dizaines d'autres tests.

Malheureusement, votre compromis ici est la vitesse. Il faut du temps pour exécuter tous ces tests, pour exécuter tous ces scripts d'installation / démontage.

Un dernier point, il peut être très difficile d'écrire une telle quantité de SQL pour tester votre ORM. C'est là que je prends une approche très désagréable (les puristes ici ne seront pas d'accord avec moi). J'utilise mon ORM pour créer mon test! Plutôt que d'avoir un script séparé pour chaque test DAL dans mon système, j'ai une phase de configuration de test qui crée les objets, les attache au contexte et les enregistre. Je cours ensuite mon test.

C'est loin d'être la solution idéale mais en pratique, je trouve que c'est beaucoup plus facile à gérer (surtout quand vous avez plusieurs milliers de tests), sinon vous créez un grand nombre de scripts. Pratique sur la pureté.

Je reviendrai sans doute sur cette réponse dans quelques années (mois / jours) et je ne suis pas d'accord avec moi-même car mes approches ont changé - mais c'est mon approche actuelle.

Pour essayer de résumer tout ce que j'ai dit ci-dessus, voici mon test d'intégration DB typique:

[Test]
public void LoadUser()
{
  this.RunTest(session => // the NH/EF session to attach the objects to
  {
    var user = new UserAccount("Mr", "Joe", "Bloggs");
    session.Save(user);
    return user.UserID;
  }, id => // the ID of the entity we need to load
  {
     var user = LoadMyUser(id); // load the entity
     Assert.AreEqual("Mr", user.Title); // test your properties
     Assert.AreEqual("Joe", user.Firstname);
     Assert.AreEqual("Bloggs", user.Lastname);
  }
}

La chose clé à remarquer ici est que les sessions des deux boucles sont complètement indépendantes. Dans votre implémentation de RunTest, vous devez vous assurer que le contexte est validé et détruit et que vos données ne peuvent provenir que de votre base de données pour la deuxième partie.

Édition 13/10/2014

J'ai dit que je réviserais probablement ce modèle au cours des prochains mois. Bien que je reste largement fidèle à l'approche que j'ai défendue ci-dessus, j'ai légèrement mis à jour mon mécanisme de test. J'ai maintenant tendance à créer les entités dans TestSetup et TestTearDown.

[SetUp]
public void Setup()
{
  this.SetupTest(session => // the NH/EF session to attach the objects to
  {
    var user = new UserAccount("Mr", "Joe", "Bloggs");
    session.Save(user);
    this.UserID =  user.UserID;
  });
}

[TearDown]
public void TearDown()
{
   this.TearDownDatabase();
}

Ensuite, testez chaque propriété individuellement

[Test]
public void TestTitle()
{
     var user = LoadMyUser(this.UserID); // load the entity
     Assert.AreEqual("Mr", user.Title);
}

[Test]
public void TestFirstname()
{
     var user = LoadMyUser(this.UserID);
     Assert.AreEqual("Joe", user.Firstname);
}

[Test]
public void TestLastname()
{
     var user = LoadMyUser(this.UserID);
     Assert.AreEqual("Bloggs", user.Lastname);
}

Il y a plusieurs raisons à cette approche:

  • Il n'y a pas d'appels de base de données supplémentaires (une configuration, un démontage)
  • Les tests sont beaucoup plus granulaires, chaque test vérifie une propriété
  • La logique Setup / TearDown est supprimée des méthodes de test elles-mêmes

Je pense que cela rend la classe de test plus simple et les tests plus granulaires (les affirmations simples sont bonnes )

Édition 05/05/2015

Une autre révision de cette approche. Bien que les configurations au niveau de la classe soient très utiles pour les tests tels que le chargement des propriétés, elles sont moins utiles lorsque les différentes configurations sont requises. Dans ce cas, la création d'une nouvelle classe pour chaque cas est exagérée.

Pour aider avec ceci j'ai maintenant tendance à avoir deux classes de base SetupPerTest et SingleSetup . Ces deux classes exposent le framework selon les besoins.

Dans SingleSetup nous avons un mécanisme très similaire à celui décrit dans ma première édition. Un exemple serait

public TestProperties : SingleSetup
{
  public int UserID {get;set;}

  public override DoSetup(ISession session)
  {
    var user = new User("Joe", "Bloggs");
    session.Save(user);
    this.UserID = user.UserID;
  }

  [Test]
  public void TestLastname()
  {
     var user = LoadMyUser(this.UserID); // load the entity
     Assert.AreEqual("Bloggs", user.Lastname);
  }

  [Test]
  public void TestFirstname()
  {
       var user = LoadMyUser(this.UserID);
       Assert.AreEqual("Joe", user.Firstname);
  }
}

Cependant, les références qui garantissent que seules les entités correctes sont chargées peuvent utiliser une approche SetupPerTest

public TestProperties : SetupPerTest
{
   [Test]
   public void EnsureCorrectReferenceIsLoaded()
   {
      int friendID = 0;
      this.RunTest(session =>
      {
         var user = CreateUserWithFriend();
         session.Save(user);
         friendID = user.Friends.Single().FriendID;
      } () =>
      {
         var user = GetUser();
         Assert.AreEqual(friendID, user.Friends.Single().FriendID);
      });
   }
   [Test]
   public void EnsureOnlyCorrectFriendsAreLoaded()
   {
      int userID = 0;
      this.RunTest(session =>
      {
         var user = CreateUserWithFriends(2);
         var user2 = CreateUserWithFriends(5);
         session.Save(user);
         session.Save(user2);
         userID = user.UserID;
      } () =>
      {
         var user = GetUser(userID);
         Assert.AreEqual(2, user.Friends.Count());
      });
   }
}

En résumé, les deux approches fonctionnent en fonction de ce que vous essayez de tester.

Je commence tout juste avec les tests unitaires et TDD en général. J'ai déjà essayé, mais maintenant je suis déterminé à l'ajouter à mon flux de travail et à écrire de meilleurs logiciels.

Hier, j'ai posé une question qui incluait cela, mais il semble que ce soit une question en soi. Je me suis assis pour commencer à implémenter une classe de service que je vais utiliser pour abstraire la logique métier des contrôleurs et mapper des modèles spécifiques et des interactions de données en utilisant EF6.

Le problème est que je me suis déjà barré parce que je ne voulais pas supprimer EF dans un dépôt (il sera toujours disponible en dehors des services pour des requêtes spécifiques, etc.) et que je voudrais tester mes services (EF Context sera utilisé) .

Ici, je suppose que c'est la question, est-ce qu'il y a un point à faire cela? Si oui, comment les gens le font-ils dans la nature à la lumière des absences fuyantes causées par IQueryable et les nombreux grands articles de Ladislav Mrnka sur le sujet des tests unitaires qui ne sont pas simples à cause des différences dans les fournisseurs Linq implémentation telle qu'apposée à une base de données spécifique.

Le code que je veux tester semble assez simple. (Ceci est juste un code fictif pour essayer de comprendre ce que je fais, je veux conduire la création en utilisant TDD)

Le contexte

public interface IContext
{
    IDbSet<Product> Products { get; set; }
    IDbSet<Category> Categories { get; set; }
    int SaveChanges();
}

public class DataContext : DbContext, IContext
{
    public IDbSet<Product> Products { get; set; }
    public IDbSet<Category> Categories { get; set; }

    public DataContext(string connectionString)
                : base(connectionString)
    {

    }
}

Un service

public class ProductService : IProductService
{
    private IContext _context;

    public ProductService(IContext dbContext)
    {
        _context = dbContext;
    }

    public IEnumerable<Product> GetAll()
    {
        var query = from p in _context.Products
                    select p;

        return query;
    }
}

Actuellement, je suis dans l'état d'esprit de faire quelques choses:

  1. Mocking EF Contexte avec quelque chose comme cette approche- Mocking EF lors de tests unitaires ou en utilisant directement un cadre moqueur sur l'interface comme moq - prendre la douleur que les tests unitaires peuvent passer mais pas nécessairement travailler de bout en bout et les sauvegarder avec des tests d'intégration?
  2. Peut-être utiliser quelque chose comme Effort pour se moquer de EF - Je ne l'ai jamais utilisé et je ne sais pas si quelqu'un d'autre l'utilise dans la nature?
  3. Pas la peine de tester quoi que ce soit qui rappelle simplement EF - donc essentiellement les méthodes de service qui appellent EF directement (getAll etc.) ne sont pas testées unitairement mais juste testées?

Quelqu'un là-bas fait-il réellement là-bas sans repo et avoir du succès?


Donc, voici la chose, Entity Framework est une mise en œuvre donc malgré le fait qu'il résume la complexité de l'interaction de la base de données, l'interaction directe est toujours couplage serré et c'est pourquoi il est déroutant de tester.

Le test unitaire consiste à tester la logique d'une fonction et chacun de ses résultats potentiels indépendamment de toute dépendance externe, qui dans ce cas est le magasin de données. Pour ce faire, vous devez pouvoir contrôler le comportement du magasin de données. Par exemple, si vous voulez affirmer que votre fonction renvoie false si l'utilisateur récupéré ne répond pas à un ensemble de critères, votre magasin de données [mocked] doit être configuré pour renvoyer systématiquement un utilisateur qui ne répond pas aux critères, et vice versa. versa pour l'assertion opposée.

Cela dit, et en acceptant le fait que EF soit une implémentation, je serais probablement favorable à l'idée d'abstraire un référentiel. Semble un peu redondant? Ce n'est pas le cas, car vous résolvez un problème qui isole votre code de l'implémentation des données.

Dans DDD, les référentiels retournent uniquement les racines agrégées, et non DAO. De cette façon, le consommateur du référentiel n'a jamais à connaître l'implémentation des données (comme il ne devrait pas l'être) et nous pouvons l'utiliser comme un exemple de la façon de résoudre ce problème. Dans ce cas, l'objet généré par EF est un DAO et, en tant que tel, doit être masqué dans votre application. C'est un autre avantage du référentiel que vous définissez. Vous pouvez définir un objet métier comme type de retour au lieu de l'objet EF. Maintenant, le repo cache les appels à EF et mappe la réponse EF à cet objet métier défini dans la signature de repos. Vous pouvez maintenant utiliser ce repo à la place de la dépendance DbContext que vous injectez dans vos classes et, par conséquent, vous pouvez maintenant vous moquer de cette interface pour vous donner le contrôle dont vous avez besoin pour tester votre code de manière isolée.

C'est un peu plus de travail et beaucoup y mettent le nez, mais cela résout un vrai problème. Il y a un fournisseur en mémoire qui a été mentionné dans une réponse différente qui pourrait être une option (je ne l'ai pas essayé), et son existence même est la preuve de la nécessité de la pratique.

Je ne suis pas du tout d'accord avec la meilleure réponse, car elle contourne le véritable problème qui consiste à isoler votre code, puis va dans le sens de tester votre cartographie. Bien sûr, testez votre cartographie si vous le souhaitez, mais adressez le problème ici et obtenez une vraie couverture de code.


En bref, je dirais non, le jus ne vaut pas le squeeze pour tester une méthode de service avec une seule ligne qui récupère les données du modèle. D'après mon expérience, les personnes qui découvrent TDD veulent absolument tout tester. Le vieux modèle d'abstraction d'une façade à un framework tiers juste pour que vous puissiez créer une maquette de cette API de frameworks avec laquelle vous bastardisez / étendiez afin que vous puissiez injecter des données fictives n'a que peu de valeur dans mon esprit. Tout le monde a une vision différente de la meilleure façon de tester les unités. J'ai tendance à être plus pragmatique ces jours-ci et je me demande si mon test apporte vraiment de la valeur au produit final, et à quel prix.


J'ai tâtonné quelque part pour arriver à ces considérations:

1- Si mon application accède à la base de données, pourquoi le test ne devrait pas? Que se passe-t-il s'il y a un problème avec l'accès aux données? Les tests doivent le savoir à l'avance et m'alerter sur le problème.

2- Le modèle de dépôt est un peu dur et prend du temps.

Je suis donc venu avec cette approche, que je ne pense pas est le meilleur, mais a répondu à mes attentes:

Use TransactionScope in the tests methods to avoid changes in the database.

Pour le faire, il faut:

1- Installez EntityFramework dans le projet de test. 2- Placez la chaîne de connexion dans le fichier app.config de Test Project. 3- Référencez le système dll System.Transactions dans le projet de test.

L'effet secondaire unique est que la graine d'identité incrémente lorsque vous essayez d'insérer, même lorsque la transaction est annulée. Mais puisque les tests sont effectués sur une base de données de développement, cela ne devrait pas poser de problème.

Exemple de code:

[TestClass]
public class NameValueTest
{
    [TestMethod]
    public void Edit()
    {
        NameValueController controller = new NameValueController();

        using(var ts = new TransactionScope()) {
            Assert.IsNotNull(controller.Edit(new Models.NameValue()
            {
                NameValueId = 1,
                name1 = "1",
                name2 = "2",
                name3 = "3",
                name4 = "4"
            }));

            //no complete, automatically abort
            //ts.Complete();
        }
    }

    [TestMethod]
    public void Create()
    {
        NameValueController controller = new NameValueController();

        using (var ts = new TransactionScope())
        {
            Assert.IsNotNull(controller.Create(new Models.NameValue()
            {
                name1 = "1",
                name2 = "2",
                name3 = "3",
                name4 = "4"
            }));

            //no complete, automatically abort
            //ts.Complete();
        }
    }
}

Je souhaite partager une approche commentée et brièvement abordée, mais montrer un exemple réel que j'utilise actuellement pour aider l' unité à tester les services basés sur l'EF.

Tout d'abord, j'aimerais utiliser le fournisseur en mémoire d'EF Core, mais il s'agit d'EF 6. De plus, pour d'autres systèmes de stockage comme RavenDB, je serais également un partisan des tests via le fournisseur de base de données en mémoire. Encore une fois - ceci est spécifiquement pour aider à tester le code basé sur EF sans beaucoup de cérémonie .

Voici les objectifs que j'ai eu en arrivant avec un modèle:

  • Il doit être simple pour les autres développeurs de l'équipe de comprendre
  • Il doit isoler le code EF au niveau le plus bas possible
  • Il ne doit pas impliquer la création d'interfaces bizarres multi-responsabilités (comme un modèle de référentiel "générique" ou "typique")
  • Il doit être facile à configurer et à configurer dans un test unitaire

Je suis d'accord avec les déclarations précédentes selon lesquelles EF est toujours un détail de mise en œuvre et il est normal que vous ayez besoin de l'abstraire pour effectuer un test unitaire «pur». Je suis également d'accord qu'idéalement, je voudrais m'assurer que le code EF fonctionne - mais cela implique une base de données sandbox, un fournisseur en mémoire, etc. Mon approche résout les deux problèmes - vous pouvez tester en toute sécurité le code EF-dependent et créer tests d'intégration pour tester votre code EF spécifiquement.

La façon dont j'ai réalisé ceci consistait simplement à encapsuler du code EF dans des classes de requêtes et de commandes dédiées. L'idée est simple: il suffit d'envelopper un code EF dans une classe et de dépendre d'une interface dans les classes qui l'auraient initialement utilisée. Le problème principal que je devais résoudre était d'éviter d'ajouter de nombreuses dépendances aux classes et de mettre en place beaucoup de code dans mes tests.

C'est là Mediatr une bibliothèque simple et utile: Mediatr . Il permet une messagerie en cours simple et il le fait en découplant les "demandes" des gestionnaires qui implémentent le code. Cela a un avantage supplémentaire de découpler le «quoi» du «comment». Par exemple, en encapsulant le code EF en petits morceaux, il vous permet de remplacer les implémentations par un autre fournisseur ou un mécanisme totalement différent, car tout ce que vous faites est d'envoyer une requête pour effectuer une action.

En utilisant l'injection de dépendance (avec ou sans cadre - votre préférence), on peut facilement se moquer du médiateur et contrôler les mécanismes de demande / réponse pour activer le test EF de l'unité.

Tout d'abord, disons que nous avons un service qui a une logique métier que nous devons tester:

public class FeatureService {

  private readonly IMediator _mediator;

  public FeatureService(IMediator mediator) {
    _mediator = mediator;
  }

  public async Task ComplexBusinessLogic() {
    // retrieve relevant objects

    var results = await _mediator.Send(new GetRelevantDbObjectsQuery());
    // normally, this would have looked like...
    // var results = _myDbContext.DbObjects.Where(x => foo).ToList();

    // perform business logic
    // ...    
  }
}

Commencez-vous à voir les avantages de cette approche? Non seulement vous encapsulez explicitement tout le code lié à EF dans des classes descriptives, mais vous permettez l'extensibilité en supprimant le problème d'implémentation du "comment" cette requête est gérée - cette classe ne se soucie pas si les objets pertinents proviennent de EF, MongoDB, ou un fichier texte.

Maintenant, pour la demande et le gestionnaire, via MediatR:

public class GetRelevantDbObjectsQuery : IRequest<DbObject[]> {
  // no input needed for this particular request,
  // but you would simply add plain properties here if needed
}

public class GetRelevantDbObjectsEFQueryHandler : IRequestHandler<GetRelevantDbObjectsQuery, DbObject[]> {
  private readonly IDbContext _db;

  public GetRelevantDbObjectsEFQueryHandler(IDbContext db) {
    _db = db;
  }

  public DbObject[] Handle(GetRelevantDbObjectsQuery message) {
    return _db.DbObjects.Where(foo => bar).ToList();
  }
}

Comme vous pouvez le voir, l'abstraction est simple et encapsulée. Il est également absolument testable parce que dans un test d'intégration, vous pouvez tester cette classe individuellement - il n'y a pas de problèmes d'affaires mélangés ici.

Alors, à quoi ressemble un test unitaire de notre service d'entités? C'est très simple. Dans ce cas, j'utilise Moq pour faire des moqueries (utilisez tout ce qui vous rend heureux):

[TestClass]
public class FeatureServiceTests {

  // mock of Mediator to handle request/responses
  private Mock<IMediator> _mediator;

  // subject under test
  private FeatureService _sut;

  [TestInitialize]
  public void Setup() {

    // set up Mediator mock
    _mediator = new Mock<IMediator>(MockBehavior.Strict);

    // inject mock as dependency
    _sut = new FeatureService(_mediator.Object);
  }

  [TestCleanup]
  public void Teardown() {

    // ensure we have called or expected all calls to Mediator
    _mediator.VerifyAll();
  }

  [TestMethod]
  public void ComplexBusinessLogic_Does_What_I_Expect() {
    var dbObjects = new List<DbObject>() {
      // set up any test objects
      new DbObject() { }
    };

    // arrange

    // setup Mediator to return our fake objects when it receives a message to perform our query
    // in practice, I find it better to create an extension method that encapsulates this setup here
    _mediator.Setup(x => x.Send(It.IsAny<GetRelevantDbObjectsQuery>(), default(CancellationToken)).ReturnsAsync(dbObjects.ToArray()).Callback(
    (GetRelevantDbObjectsQuery message, CancellationToken token) => {
       // using Moq Callback functionality, you can make assertions
       // on expected request being passed in
       Assert.IsNotNull(message);
    });

    // act
    _sut.ComplexBusinessLogic();

    // assertions
  }

}

Vous pouvez voir tout ce dont nous avons besoin est une configuration unique et nous n'avons même pas besoin de configurer quoi que ce soit d'autre - c'est un test unitaire très simple. Soyons clairs: il est totalement possible de se passer de quelque chose comme Mediatr (on implémenterait simplement une interface et on se moquerait des tests, par exemple IGetRelevantDbObjectsQuery ), mais en pratique pour une base de code importante avec de nombreuses fonctionnalités et requêtes / commandes, j'adore l'encapsulation et le soutien DI inné offre Mediatr.

Si vous vous demandez comment j'organise ces cours, c'est plutôt simple:

- MyProject
  - Features
    - MyFeature
      - Queries
      - Commands
      - Services
      - DependencyConfig.cs (Ninject feature modules)

L'organisation par tranches de fonction est à côté du but, mais cela permet de garder ensemble tout le code pertinent / dépendant et de le découvrir facilement. Plus important encore, je sépare les requêtes par rapport aux commandes - suivant le principe de commande / séparation des requêtes .

Cela répond à tous mes critères: c'est une cérémonie basse, c'est facile à comprendre, et il y a des avantages cachés supplémentaires. Par exemple, comment gérez-vous les modifications d'enregistrement? Maintenant, vous pouvez simplifier votre contexte Db en utilisant une interface de rôle ( IUnitOfWork.SaveChangesAsync() ) et en simulant des appels à l'interface de rôle unique ou vous pouvez encapsuler la validation / annulation dans votre RequestHandlers - mais vous préférez le faire à vous , tant que c'est maintenable. For example, I was tempted to create a single generic request/handler where you'd just pass an EF object and it would save/update/remove it--but you have to ask what your intention is and remember that if you wanted to swap out the handler with another storage provider/implementation, you should probably create explicit commands/queries that represent what you intend to do. More often than not, a single service or feature will need something specific--don't create generic stuff before you have a need for it.

There are of course caveats to this pattern--you can go too far with a simple pub/sub mechanism. I've limited my implementation to only abstracting EF-related code, but adventurous developers could start using MediatR to go overboard and message-ize everything--something good code review practices and peer reviews should catch. That's a process issue, not an issue with MediatR, so just be cognizant of how you're using this pattern.

You wanted a concrete example of how people are unit testing/mocking EF and this is an approach that's working successfully for us on our project--and the team is super happy with how easy it is to adopt. J'espère que ça aide! As with all things in programming, there are multiple approaches and it all depends on what you want to achieve. I value simplicity, ease of use, maintainability, and discoverability--and this solution meets all those demands.


Si vous voulez un code de test unitaire , vous devez isoler le code que vous voulez tester (dans ce cas, votre service) à partir de ressources externes (par exemple des bases de données). Vous pouvez probablement le faire avec une sorte de fournisseur d'EF en mémoire , mais un moyen beaucoup plus courant consiste à faire abstraction de votre implémentation EF, par exemple avec une sorte de modèle de référentiel. Sans cette isolation, les tests que vous écrivez seront des tests d'intégration, pas des tests unitaires.

Pour tester le code EF, j'écris des tests d'intégration automatisés pour mes dépôts qui écrivent différentes lignes dans la base de données, puis j'appelle les implémentations de mon référentiel pour m'assurer qu'elles se comportent comme prévu (par ex. qu'ils sont triés dans le bon ordre).

Il s'agit de tests d'intégration et non de tests unitaires, car les tests reposent sur la présence d'une connexion à la base de données et l'installation du dernier schéma mis à jour dans la base de données cible.


There is Effort which is an in memory entity framework database provider. I've not actually tried it... Haa just spotted this was mentioned in the question!

Alternatively you could switch to EntityFrameworkCore which has an in memory database provider built-in.

https://blog.goyello.com/2016/07/14/save-time-mocking-use-your-real-entity-framework-dbcontext-in-unit-tests/

https://github.com/tamasflamich/effort

I used a factory to get a context, so i can create the context close to its use. This seems to work locally in visual studio but not on my TeamCity build server, not sure why yet.

return new MyContext(@"Server=(localdb)\mssqllocaldb;Database=EFProviders.InMemory;Trusted_Connection=True;");




entity-framework-6.1