web-dev-qa-db-fra.com

Existe-t-il un fournisseur en mémoire pour Entity Framework?

Je suis un code de test unitaire écrit sur le ADO .NET Entity Framework. Je voudrais remplir une base de données en mémoire avec des lignes et m'assurer que mon code les récupère correctement.

Je peux me moquer d'Entity Framework à l'aide de Rhino Mocks, mais cela ne serait pas suffisant. Je dirais à la requête quelles entités me retourner. Cela ne testerait ni la clause where ni les instructions .Include (). Je veux être sûr que ma clause where correspond uniquement aux lignes que je souhaite et à aucune autre. Je veux être sûr d'avoir demandé les entités dont j'ai besoin, et aucune d'elles.

Par exemple:

class CustomerService
{
    ObjectQuery<Customer> _customerSource;
    public CustomerService(ObjectQuery<Customer> customerSource)
    {
        _customerSource = customerSource;
    }
    public Customer GetCustomerById(int customerId)
    {
        var customers = from c in _customerSource.Include("Order")
            where c.CustomerID == customerId
            select c;
        return customers.FirstOrDefault();
    }
}

Si je me moque de ObjectQuery pour renvoyer un client connu contenant des commandes, comment puis-je savoir que CustomerService a la clause right where et include? Je préfère insérer des lignes de client et des lignes de commande, puis affirmer que le bon client a été sélectionné et que les commandes sont remplies.

35
Michael L Perry

Il n’existe actuellement aucun fournisseur en mémoire pour EF, mais si vous examinez Highway.Data, il possède une interface d’abstraction de base et un InMemoryDataContext.

Test d'accès aux données et d'EF avec Highway.Data

7
Devlin Liles

Un fournisseur InMemory est inclus dans EF7 (pré-version).

Vous pouvez utiliser le paquet NuGet , ou en savoir plus à ce sujet dans le repo EF sur GitHub ( view source ).

16
Shimmy

L'article http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort describe - Effort -Entity est un fournisseur exécuté en mémoire.

Vous pouvez toujours utiliser vos classes DbContext ou ObjectContext dans des tests unitaires sans avoir à disposer d'une base de données réelle.

13
Michael Freidgeim

Une meilleure approche pourrait consister à utiliser le modèle Repository pour encapsuler votre code EF. Lorsque vous testez vos services, vous pouvez utiliser des simulacres ou des faux. Lors du test de vos référentiels, vous souhaiterez utiliser la vraie base de données pour vous assurer d'obtenir les résultats escomptés.

9
Andrew Peters

Oui, il existe au moins un fournisseur de ce type - SQLite . Je l'ai utilisé un peu et ça marche. Aussi, vous pouvez essayer SQL Server Compact . C'est une base de données intégrée et des fournisseurs EF également.
Modifier:
SQLite prend en charge les bases de données en mémoire ( link1 ). Tout ce dont vous avez besoin est de spécifier une chaîne de connexion du type: "Source de données =: memory:; Version = 3; New = True;". Si vous avez besoin d'un exemple, vous pouvez regarder SharpArchitecture .

6
zihotki

Je ne connais pas Entity Framework ni la classe ObjectQuery, mais si la méthode Include est virtuelle, vous pouvez vous en moquer comme ceci:

// Arrange
var customerSourceStub = MockRepository.GenerateStub<ObjectQuery<Customer>>();
var customers = new Customer[] 
{
    // Populate your customers as if they were coming from DB
};
customerSourceStub
    .Stub(x => x.Include("Order"))
    .Return(customers);
var sut = new CustomerService(customerSourceStub);

// Act
var actual = sut.GetCustomerById(5);

// Assert
Assert.IsNotNull(actual);
Assert.AreEqual(5, actual.Id);
2
Darin Dimitrov

Vous pouvez essayer SQL Server Compact mais il a quelques limitations assez sauvages:

  • SQL Server Compact ne prend pas en charge les expressions SKIP dans les requêtes de pagination lorsqu'il est utilisé avec Entity Framework
  • SQL Server Compact ne prend pas en charge les entités avec des clés ou des valeurs générées par le serveur lorsqu'il est utilisé avec Entity Framework
  • Aucune jointure externe, assembler, modulo sur des flotteurs, des agrégats
1
Chris S

Dans EF Core , il existe deux options principales pour cela:

  1. Mode SQLite en mémoire vous permet d’écrire des tests efficaces sur un fournisseur qui se comporte comme une base de données relationnelle.
  2. Le fournisseur InMemory est un fournisseur léger, avec des dépendances minimales, mais qui ne se comporte pas toujours comme une base de données relationnelle.

J'utilise SQLite et prend en charge toutes les requêtes que je dois faire avec la base de données de production Azure SQL.

0
Michael Freidgeim