我正在使用EF Core非实体模型和get存储过程调用。请参见下面的示例代码
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()。因此,建议我如何编写测试用例。
提前谢谢。
一位湿婆
发布于 2019-07-08 17:59:30
为DbQuery<TQuery>
设置的实际FromSql模拟与DbSet<TEntity>
相同,因此OP链接是相关的(尽管它是一个catch all实现,但如果需要匹配FromSql sql/参数,则需要进行额外的模拟设置;警告:它很快就会变得丑陋)。
您需要使用可查询序列模拟DbQuery<TQuery>
,按照OP链接模拟查询提供程序(使用所需的任何特定模拟匹配进行扩展),然后将DbQuery模拟对象分配给DbContext .Query<TQuery>()
方法和DbContext DbQuery<TQuery>
属性。
在模拟DbQuery方面,这是我用来创建一个的:
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,我将提供程序更改为查询提供程序模拟(根据为CreateQuery设置的模拟操作):
mock.As<IQueryable<TEntity>>().Setup(m => m.Provider).Returns(queryProviderMock.Object);
如果您想节省一些时间,我最终将上面的代码包装在一个库中:https://github.com/rgvlee/EntityFrameworkCore.Testing
https://stackoverflow.com/questions/56071216
复制相似问题