我是新來的嘲弄。我想嘲笑我的基礎知識庫,這取決於實體框架6 DbContext但我失敗了。我在谷歌搜索了很多,但沒有得到任何足夠的結果。最後,我在testing with async queries上得到了一個例子,並嘗試關注,但它對我有用。如何模擬實體框架6異步方法?
這裏是我的代碼:
的DbContext:
public class TimeSketchContext : DbContext
{
public virtual DbSet<EmployeeSkill> EmployeeSkill { get; set; }
}
基礎信息庫:
public class BaseRepository<T> : IRepositoryBase<T> where T : class, IEntity, new()
{
protected readonly DbContext InnerDbContext;
protected DbSet<T> InnerDbSet;
public BaseRepository(DbContext innerDbContext)
{
InnerDbContext = innerDbContext;
InnerDbSet = InnerDbContext.Set<T>();
}
public virtual Task<T> FindAsync(long id)
{
return InnerDbSet.FirstOrDefaultAsync(x=>x.Id == id);
}
}
測試:
[Fact]
public async Task DbTest()
{
var dummyData = GetEmployeeSkills();
var mockSet = new Mock<DbSet<EmployeeSkill>>();
mockSet.As<IDbAsyncEnumerable<EmployeeSkill>>()
.Setup(x => x.GetAsyncEnumerator())
.Returns(new TestDbAsyncEnumerator<EmployeeSkill>(dummyData.GetEnumerator()));
mockSet.As<IQueryable<EmployeeSkill>>()
.Setup(x => x.Provider)
.Returns(new TestDbAsyncQueryProvider<EmployeeSkill>(dummyData.Provider));
mockSet.As<IQueryable<EmployeeSkill>>().Setup(m => m.Expression).Returns(dummyData.Expression);
mockSet.As<IQueryable<EmployeeSkill>>().Setup(m => m.ElementType).Returns(dummyData.ElementType);
mockSet.As<IQueryable<EmployeeSkill>>().Setup(m => m.GetEnumerator()).Returns(dummyData.GetEnumerator());
var mockContext = new Mock<TimeSketchContext>();
mockContext.Setup(c => c.EmployeeSkill).Returns(mockSet.Object);
var baseRepository = new BaseRepository<EmployeeSkill>(mockContext.Object);
var data = await baseRepository.FindAsync(1);
Assert.NotEqual(null, data);
}
private EmployeeSkill GetEmployeeSkill()
{
return new EmployeeSkill
{
SkillDescription = "SkillDescription",
SkillName = "SkillName",
Id = 1
};
}
private IQueryable<EmployeeSkill> GetEmployeeSkills()
{
return new List<EmployeeSkill>
{
GetEmployeeSkill(),
GetEmployeeSkill(),
GetEmployeeSkill(),
}.AsQueryable();
}
結果是:
Assert.NotEqual()失敗
我認爲問題是
public BaseRepository(DbContext innerDbContext)
{
InnerDbContext = innerDbContext;
InnerDbSet = InnerDbContext.Set<T>(); <<<<<<<<<<<
}
但不`噸明白爲什麼,以及如何解決這個問題。
我使用:
- 的Visual Studio 2013旗艦版
- 起訂量
- 的xUnit
Thank`s提前。
對未來的讀者:如果你是在所有地方注入DbContext並且無法將其抽象到存儲庫/接口,並且絕對需要「模擬」它,非虛擬化和全部,您可以使用Microsoft Fakes Assemblies來實現此目的,因爲它可以實現一些幻想的IL東西讓你提供一個替代實現甚至一個對象的非虛擬方法。 –
我強烈建議查看一下EF單元測試工具「Effort」(https://effort.codeplex.com/),它可以創建一個足夠真實的EF內存數據庫來測試。我們嘲笑EF也經歷了許多令人頭痛的事情,但在一天結束時,測試EF嘲笑是一個蘋果對桔子的失敗。 (舉一個例子,模擬測試使用L2O而不是L2E。) – RJB
它看起來是一個不錯的工具,稍後會進行檢查。不管感謝@RJB –