我想要編寫單元測試(與NUnit的)服務層,它的用途:的EntityFramework,DbContextScope和精力 - 例外:的DbContext已配置的單元測試裏面
- 實體框架作爲數據訪問層
- DbContextScope用於管理DbContext生存期
我還使用Effort.EF6在單元測試中模擬DbContext。不幸的是,我找不到一種方法使DbContextScope與Effort兼容,這樣我就可以正確地測試所有的情況。
概述代碼
服務層包括其中做一些業務邏輯類(服務)。每種方法都被視爲完整的交易,以context.SaveChanges()
結束。例如:
private IDbContextScopeFactory _dbContextScopeFactory;
public DepartmentsService(IDbContextScopeFactory dbContextScopeFactory)
{
_dbContextScopeFactory = dbContextScopeFactory;
}
public BusinessModel.Department Insert(BusinessModel.Department department)
{
using (var dbContextScope = _dbContextScopeFactory.Create())
{
// Validation
ValidateAndThrowOnFailure(department, new DepartmentAddValidator());
// Operation
DBModel.Department newDepartment = Mapper.Map<DBModel.Department>(department);
newDepartment.InsertDateUTC = DateTime.UtcNow;
dbContextScope.DbContexts.Get<DPSContext>().Departments.Add(newDepartment);
dbContextScope.SaveChanges();
return Mapper.Map<BusinessModel.Department>(newDepartment);
}
}
單元測試這樣的方法,我做每個測試之前一些準備:
private IDepartmentsService _departmentsService;
private IDbContextScopeFactory _dbContextScopeFactory;
private IDbContextFactory _dbContextFactory;
private DBModel.DPSContext _dbEntities;
[SetUp]
public void ReInitializeTest()
{
// Setup DbContext with Effort.EF6
string connStr = ConfigurationManager.ConnectionStrings["DPSContext"].ConnectionString;
DbConnection connection = EntityConnectionFactory.CreateTransient(connStr);
_dbEntities = new DBModel.DPSContext(connection);
// Fill DbContext with in-memory data
_dbEntities.Departments.AddRange(DataInitializer.GetDepartments());
_dbEntities.SaveChanges();
// Mock IDbContextFactory so that it returns in-memory context
var contextFactoryMock = new Mock<IDbContextFactory>();
contextFactoryMock
.Setup(f => f.CreateDbContext<DBModel.DPSContext>())
.Returns(_dbEntities);
_dbContextFactory = contextFactoryMock.Object;
// Setup DbContextScopeFactory to use mocked context
_dbContextScopeFactory = new DbContextScopeFactory(_dbContextFactory);
_departmentsService = new DepartmentsService(_dbContextScopeFactory);
}
的測試和問題
下面是一個簡單的單元測試:
[Test]
public void Insert_WhenValidModelPassed_ShouldInsertNewRecord()
{
// Given
BusinessModel.Department newDepartment = DataInitializer.GetExampleOfNewDepartment();
// When
_departmentsService.Insert(newDepartment);
// Then
Assert.AreEqual(3, _dbEntities.Departments.Count());
}
的問題是,測試失敗,異常:
System.InvalidOperationException : The operation cannot be completed because the DbContext has been disposed.
似乎DbContextScope使用內部Insert
方法在內部部署分配上下文在using
塊的末端,從而當被調用時的Assert
拋出異常。有沒有人遇到過類似的問題,或者只是知道我應該怎麼做才能成功地測試這種類似的情況?