实体框架核心FromSql模拟测试用例 [英] Entity Framework Core FromSql mock test cases
问题描述
我正在使用带有获取存储过程调用的EF Core非实体模型。参见下面的示例代码
I am using EF Core non-entity model with get stored procedure calling. See below sample code
context.Query<ClassDTO>().FromSql("SpName @Param1, @Param2, @Param3",
new SqlParameter[] { param1, param2, param3 }).ToList();
代码运行正常。但是我需要编写模拟测试用例。
Code is working fine. But I need to write mock test cases.
有人可以帮我吗?如何模拟 Context.Query
或如何为该代码编写测试用例?
Can anyone help me out? How to mock Context.Query
or how to write test cases for this code?
我尝试实现以下方法方式:
I tried to implement the follow way:
https://nodogmablog.bryanhogan.net/2017/11/unit-testing-entity-framework-core-stored-procedures/
但是它将适用于
** productContext.Products.MockFromSql(...)
But it will work for ** productContext.Products.MockFromSql(...)
但是对我来说就像productContext.Query .MockFromSql()。因此,建议我如何编写测试用例。
But for me It is Like productContext.Query.MockFromSql(). So advice me how to write test cases.
预先感谢。
A Siva
推荐答案
为 DbQuery< TQuery>
设置的实际FromSql模拟与 DbSet< TEntity>
因此,OP链接是相关的(尽管这是一个完整的实现,如果需要在FromSql sql / parameters上进行匹配,则需要进行其他模拟设置;警告:它很快就会变得丑陋。)
The actual FromSql mock set up for a DbQuery<TQuery>
is the same as a DbSet<TEntity>
so the OP link is relevant (although it's a catch all implementation, if you need to match on the FromSql sql/parameters you'll need to do additional mock set up; warning: it gets ugly quickly).
You need to mock the DbQuery<TQuery>
with a queryable sequence, mock the query provider as per the OP link (extended with any specific mock matching that you need) and then assign the DbQuery mocked object to BOTH the DbContext .Query<TQuery>()
method and the DbContext DbQuery<TQuery>
property.
在模拟DbQuery方面,是我用来创建的对象:
In terms of mocking a DbQuery, this is what I use to create one:
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;
}
然后,如果我需要支持FromSql,我将提供程序更改为查询提供程序模拟(根据OP为CreateQuery进行的模拟设置):
Then if I need to support FromSql I change the provider to a query provider mock (as per the OP the mock set up for CreateQuery):
mock.As<IQueryable<TEntity>>().Setup(m => m.Provider).Returns(queryProviderMock.Object);
如果您想节省一些时间,我最终将以上内容包装在一个库中: https://github.com/rgvlee/EntityFrameworkCore.Testing
I ended up wrapping the above in a library if you want to save yourself some time: https://github.com/rgvlee/EntityFrameworkCore.Testing
这篇关于实体框架核心FromSql模拟测试用例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!