我正在使用實體框架,並有一個通用的存儲庫方法,允許我查詢DbSet
並且還包括導航屬性。我正在嘗試爲使用這段代碼的代碼編寫一個單元測試,我需要模擬它進行單元測試。我正在使用Moq。Moq - 嘲諷複雜的存儲庫方法 - 不返回列表對象
這是存儲庫方法 - 它是一種方法,允許我使用表達式進行查詢,並且還包括我想要的相關導航屬性。我在Pluralsight的Enterprise課程中看到了Julie Lerman的EF模式。
public IEnumerable<TEntity> FindByInclude(Expression<Func<TEntity, bool>> predicate,
params Expression<Func<TEntity, object>>[] includeProperties)
{
var query = GetAllIncluding(includeProperties);
IEnumerable<TEntity> results = query.Where(predicate).ToList();
return results;
}
private IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] includeProperties)
{
IQueryable<TEntity> queryable = DbSet.AsNoTracking();
return includeProperties.Aggregate
(queryable, (current, includeProperty) => current.Include(includeProperty));
}
這裏是我如何在我的代碼使用這種方法調用的一個例子(我只是顯示該方法的相關部分):
public ApiResult DeleteLocation(int id)
{
var location = _locationRepository
.FindByInclude(l => l.Id == id, l => l.LocationRegions, l => l.Pools)
.Single();
所以這個查詢會帶回一個單Location
實體由我通過的ID和相關的LocationRooms
和Staff
收藏。
如何設置Moq爲FindByInclude
方法?以下是我對我的單元測試模擬設置:
var mockLocationRepository = new Mock<ILocationRepository>();
var location = new Location {Id = 1,Name = "LocationName", LocationRooms = new List<LocationRoom>(), Staff = new List<Staff>()};
mockLocationRepository.Setup(r => r.FindByInclude(l => l.Id == It.IsAny<int>(), l => l.LocationRooms, l => l.Staff))
.Returns(() => new List<Location> { location });
從這裏顯示的起訂量設置代碼 - 我想我應該回去了1個位置的列表 - 我ID爲1所指定的位置對象。但是,當我運行我的單元測試,並打這個代碼 - FindByInclude
的設置方法返回一個空列表。因此,當DeleteLocation
方法中的代碼被擊中並且調用Single()方法時,我收到「元素不包含序列」的錯誤。
我認爲問題是我的Moq設置爲FindByInclude
方法的語法有問題,但不知道什麼是錯的。
Thanks Nkosi - 這正是我需要:) – user1750537