I am writing automated tests for a project I've been working on to become more familiar with MVC, EntityFramework (code first), unit testing, and Moq.
I have a section in my Repository
class which sets a LastModified
field of my models whenever Repository.SaveChanges()
is called by the controller that works like this (MyModelBase is a base class):
public void RepoSaveChanges()
{
foreach(var entry in _dbContext.ChangeTracker.Entities().Where(e => e.State == EntityState.Modified))
{
MyModelBase model = entry.Entity as MyModelBase;
if (model != null)
{
model.LastModified = DateTime.Now;
}
}
_dbContext.SaveChanges();
}
This works fine during application run time in the normal online environment, but it breaks when running in test methods. I use Moq to mock the DbSets in the DbContext and set up my test data.
Here's the weird part for me: My unit tests run fine (pass) but they don't ever actually enter the foreach
loop - it hangs when ChangeTracker.Entities()
is accessed and quits the loop, jumping down to _dbContext.SaveChanges()
. There is no error.
However, on a friend's machine who shares the project with me, he gets an SQLException when ChangeTracker.Entities()
is accessed. I do have SQLExceptions checked as thrown in VS2015 and there is no output or other indication of an exception on my side.
Result StackTrace:
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) ....Result Message:
Test method MyProject.Tests.TestClasses.MyControllerTests.TestCreate threw exception: System.Data.SqlClient.SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
Finally, my question is: is there a way to use Moq to mock the ChangeTracker (I suspect not from prior investigation), or is there another approach I can take to my RepoSaveChanges()
that automatically sets a property? Without accessing ChangeTracker.Entities()
I would need to have update logic to set the LastModified
field for every model type that has it. Similarly, I feel like avoiding the use of that API/part of the framework because testing is being stubborn is not ideal.
Does anyone have any insight as to why the SQLException is not thrown/cannot be caught on my machine? Or any suggestions on how to use ChangeTracker.Entities()
in unit tests? I would only set the LastModified
property individually across all my models and controllers as a last resort.
Aucun commentaire:
Enregistrer un commentaire