我正在爲一個項目編寫自動化測試,我一直致力於更熟悉MVC,EntityFramework(代碼優先),單元測試和Moq。DbContext.ChangeTracker在自動化測試中拋出SQLException
我在Repository
類部,其設定我的模型的LastModified
場每當Repository.SaveChanges()
由這樣的作品(MyModelBase是一個基類)控制器稱爲:
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();
}
也能正常工作期間應用程序運行時間在正常的在線環境中,但在運行測試方法時會中斷。我使用Moq來模擬DbContext中的DbSets並設置我的測試數據。
下面是我怪異的一部分: 我的單元測試運行正常(合格),但他們永遠無法真正進入foreach
循環 - 它掛在ChangeTracker.Entities()
訪問和退出循環,跳下來_dbContext.SaveChanges()
。沒有錯誤。
但是,在與我共享項目的朋友的機器上,當訪問ChangeTracker.Entities()
時,他得到SQLException。我確實在VS2015中檢查了SQLExceptions,並且沒有輸出或其他異常。
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)
最後,我的問題是:是否有使用起訂量嘲笑ChangeTracker(我懷疑不是從先前的調查)的方式,或者是有另一種方法我可以把我的RepoSaveChanges()
自動設置的屬性?沒有訪問ChangeTracker.Entities()
我需要有更新邏輯設置LastModified
字段爲每個模型類型。同樣,我覺得要避免使用該API /框架的一部分,因爲測試是固執的並不理想。
有沒有人有任何洞察力,爲什麼不拋出SQLException /不能在我的機器上捕獲?或者有關如何在單元測試中使用ChangeTracker.Entities()
的建議?作爲最後手段,我只會在所有模型和控制器中單獨設置LastModified
屬性。
更新: 更多示例代碼已被要求,所以讓我再詳細。我嘲笑一個的DbContext使用最小起訂量,然後嘲笑包含在的DbContext的DbSet對象:
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
這是什麼版本的EF? –
@ E-BAT EF版本6.1.3 – Softerware