我正在使用带有获取存储过程调用的EF Core非实体模型。参见下面的示例代码
context.Query<ClassDTO>().FromSql("SpName @Param1, @Param2, @Param3",
new SqlParameter[] { param1, param2, param3 }).ToList();
代码工作正常。但是我需要编写模拟测试用例。
有人可以帮我吗?如何模拟Context.Query
或如何为此代码编写测试用例?
我尝试实现以下方法:
https://nodogmablog.bryanhogan.net/2017/11/unit-testing-entity-framework-core-stored-procedures/
但它适用于 ** productContext.Products.MockFromSql(...)
但是对我来说,就像productContext.Query.MockFromSql()。因此,建议我如何编写测试用例。
谢谢。
西瓦
答案 0 :(得分:0)
为DbQuery<TQuery>
设置的实际FromSql模拟与DbSet<TEntity>
相同,因此OP链接是相关的(尽管这是所有实现,但是如果您需要在FromSql sql /参数,您需要进行其他模拟设置;警告:它很快就会变得难看)。
您需要使用可查询的序列模拟DbQuery<TQuery>
,按照OP链接模拟查询提供程序(扩展了所需的任何特定模拟匹配),然后将DbQuery模拟对象分配给DbContext { {1}}方法和DbContext .Query<TQuery>()
属性。
就模拟DbQuery而言,这就是我用来创建DbQuery的方法:
DbQuery<TQuery>
然后,如果我需要支持FromSql,我将提供程序更改为查询提供程序模拟(按照OP为CreateQuery设置的模拟):
public static Mock<DbQuery<TQuery>> CreateDbQueryMock<TQuery>(this DbQuery<TQuery> dbQuery, IEnumerable<TQuery> sequence) where TQuery : class {
var dbQueryMock = new Mock<DbQuery<TQuery>>();
var queryableSequence = sequence.AsQueryable();
dbQueryMock.As<IAsyncEnumerableAccessor<TQuery>>().Setup(m => m.AsyncEnumerable).Returns(queryableSequence.ToAsyncEnumerable);
dbQueryMock.As<IQueryable<TQuery>>().Setup(m => m.ElementType).Returns(queryableSequence.ElementType);
dbQueryMock.As<IQueryable<TQuery>>().Setup(m => m.Expression).Returns(queryableSequence.Expression);
dbQueryMock.As<IEnumerable>().Setup(m => m.GetEnumerator()).Returns(queryableSequence.GetEnumerator());
dbQueryMock.As<IEnumerable<TQuery>>().Setup(m => m.GetEnumerator()).Returns(queryableSequence.GetEnumerator());
dbQueryMock.As<IQueryable<TQuery>>().Setup(m => m.Provider).Returns(queryableSequence.Provider);
return dbQueryMock;
}
如果您想节省一些时间,我最终将以上内容包装在一个库中:https://github.com/rgvlee/EntityFrameworkCore.DbContextBackedMock.Moq