【发布时间】:2016-03-16 22:53:35
【问题描述】:
我制作了一个 DbContext 模拟并填充了测试数据。 DbSet 是一个受保护的类,所以不能模拟结果,所以我找到了一个扩展方法。
public static class DbSetMocking
{
private static Mock<DbSet<T>> CreateMockSet<T>(IQueryable<T> data)
where T : class
{
var queryableData = data.AsQueryable();
var mockSet = new Mock<DbSet<T>>();
mockSet.As<IQueryable<T>>().Setup(m => m.Provider)
.Returns(queryableData.Provider);
mockSet.As<IQueryable<T>>().Setup(m => m.Expression)
.Returns(queryableData.Expression);
mockSet.As<IQueryable<T>>().Setup(m => m.ElementType)
.Returns(queryableData.ElementType);
mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator())
.Returns(queryableData.GetEnumerator());
return mockSet;
}
public static IReturnsResult<TContext> ReturnsDbSet<TEntity, TContext>(this IReturns<TContext, DbSet<TEntity>> setup, TEntity[] entities)
where TEntity : class
where TContext : DbContext
{
var mockSet = CreateMockSet(entities.AsQueryable());
return setup.Returns(mockSet.Object);
}
public static IReturnsResult<TContext> ReturnsDbSet<TEntity, TContext>(this IReturns<TContext, DbSet<TEntity>> setup, IQueryable<TEntity> entities)
where TEntity : class
where TContext : DbContext
{
var mockSet = CreateMockSet(entities);
return setup.Returns(mockSet.Object);
}
public static IReturnsResult<TContext> ReturnsDbSet<TEntity, TContext>(this IReturns<TContext, DbSet<TEntity>> setup, IEnumerable<TEntity> entities)
where TEntity : class
where TContext : DbContext
{
var mockSet = CreateMockSet(entities.AsQueryable());
return setup.Returns(mockSet.Object);
}
}
创建 DbContext 的 Mock:
var db = new Mock<DbContext>();
//Populate
this.db.Setup(x => x.MyObjects).ReturnsDbSet(
new List<MyObject>
{
new MyObject{Id=1, Description="Test"},
}
);
其次,我正在尝试扩展 Mocks 以包含 Find(id) 和 FindAsync(id) 方法。这些方法被放置在 DbSetMocking 类中。查找方法工作正常:
mockSet.Setup(m => m.Find(It.IsAny<object[]>()))
.Returns<object[]>(id => StaticMethodtoFindStuff<T>(queryableData, id));
但是,我无法让 FindAsync 方法工作。这是我迄今为止尝试过的:
mockSet.Setup(m => m.FindAsync(It.IsAny<object[]>()))
.Returns(Task.FromResult(StaticMethodtoFindStuff<T>(queryableData, 1)));
这个可行,但是我无法访问该函数设置的参数。试过这个,编译工作正常,但执行失败并显示错误消息:
“System.Object[]”类型的对象无法转换为“System.Threading.Tasks.Task`1[System.Object[]]”类型。
mockSet.Setup(m => m.FindAsync(It.IsAny<object[]>()))
.Returns<Task<object[]>>(d =>
{
return Task.FromResult(StaticMethodtoFindStuff<T>(queryableData, d));
});
有人知道我如何实现这个功能吗?
【问题讨论】:
标签: c# entity-framework unit-testing mocking moq