7
votes

Dbcontext.changTracker dans les tests automatisés jette la sqlexception

J'écris des tests automatisés pour un projet, je travaille à devenir plus familier avec MVC, EntityFramework (code en premier), tests unitaires et MOQ.

J'ai une section dans mon référentiel code> class code> qui définit un champ lastmodified code> de mes modèles chaque fois que référentiel.savechanges () code> est appelé par le Contrôleur qui fonctionne comme ceci (MyModelBase est une classe de base): p>

var mockContext = new Mock<MyApplicationDbContext>();   //MyApplicationDbContext extends DbContext

Person p = new Person();
p.Name = "Bob";
p.Employer = "Superstore";

List<Person> list = new List<Person>();
list.Add(p);

var queryable = list.AsQueryable();

Mock<DbSet<Person>> mockPersonSet = new Mock<DbSet<Person>>();
mockPersonSet.As<IQueryable<Person>>().Setup(set => set.Provider).Returns(queryable.Provider);
mockPersonSet.As<IQueryable<Person>>().Setup(set => set.Expression).Returns(queryable.Expression);
mockPersonSet.As<IQueryable<Person>>().Setup(set => set.ElementType).Returns(queryable.ElementType);
mockPersonSet.As<IQueryable<Person>>().Setup(set => set.GetEnumerator()).Returns(() => queryable.GetEnumerator()); 

DbSet<Person> dbSet = mockPersonSet.Object as DbSet<Person>;
mockPersonSet.Setup(set => set.Local).Returns(dbSet.Local);

mockContext.Setup(context => context.Set<Person>()).Returns(mockPersonSet.Object);
mockContext.Setup(context => context.Persons).Returns(mockPersonSet.Object));

//Create the repo using the mock data context I created
PersonRepository repo = new PersonRepository(mockContext.Object);

//Then finally create the controller and perform the test
PersonController controller = new PersonController(repo);
var result = controller.Create(someEmployerID); //Sometimes throws an SQLException when DbContext.SaveChanges() is called


2 commentaires

Quelle version de ef est-ce?


@ E-BAT EF version 6.1.3


3 Réponses :


0
votes

Quelle est votre erreur indique que cela ne peut pas créer de connexion à votre base de données. Cela se produit lors de la création de votre dBContext où EF commencera à faire des choses comme Vérification si votre base de données doit être migrée.

Il me semble que vous devez aussi vous moquer du constructeur de votre dbcontext. Je ne suis pas trop familier avec MOQ elle-même, mais si je lisais votre code correctement, je ne vous vois pas moquer du constructeur.


2 commentaires

Je ne vois aucune valeur dans la moqueur du constructeur car mes tests ne se connectent à aucune base de données, je dois pouvoir utiliser l'API DBContext.Changetracker.entries () API Offline. Le mieux que je puisse faire est de fournir une chaîne de connexion alternative pour ne pas vous connecter.


Mon point est qu'un dBContext attend une connexion de base de données. Si vous voulez un dbcontext moqueur, vous devez vous moquer du constructeur afin que votre dbcontext soit créé, vous obtenez une fausse version - une sans connexion de base de données



0
votes

L'exception indique qu'il ne peut pas créer de connexion à DB, je soupçonne que vous et votre ami avez des chaînes de connexion différentes dans les fichiers app.config ou que votre ami n'a pas accès à la DB.

réellement vous êtes Écrire un Test d'intégration em> test, pas Unité em> test. Les tests d'unités sont inscrits spécifiquement pour un objet sous tests. Dans votre code de cas: P>

private IRepository _repository;    
public PersonController() : this(new Repository()) //real implementation
{}

public PersonController(IRepository repository)
{
    _repository = repository;
}

// your test
var reporitory = new Mock<IRepository>();
var controller = new PersonController(repository.Object);
controller.CreateEmployee(someId);
// assert that your repository was called
repository.Verify(...);


1 commentaires

Bonjour, merci pour votre contribution. En fait, j'ai laissé cette partie de l'exemple du code par erreur. J'utilise un référentiel qui me permet de passer mon DBContext moqueur. Ce n'est pas une "réelle implémentation" comme vous l'avez mentionné. Tous mes méthodes HTTP Obtenir des méthodes sur le contrôleur fonctionnent avec le référentiel d'amende, le problème se pose lorsque une logique dans le repo tente d'utiliser l'API DBContext.Changetracker.entries ().



2
votes

Je suis arrivé à une solution moins que idéale pour moi-même mais assez bon pour me permettre de passer à autre chose. J'ai contourné le dbcontext.changetracker.entries () code> API en ajoutant simplement un niveau d'abstraction à ma classe qui s'étend dbContext code> appelé myApplicationDBContext code>:

List<SomeModel> addedEntries = new List<SomeModel>();
addedEntries.add(someModelWhichWillBeAddedByTheController);
mockContext.Setup(context => context.AddedEntries).Returns(addedEntries);


0 commentaires