实体框架核心FromSql模拟测试用例 [英] Entity Framework Core FromSql mock test cases

查看:74
本文介绍了实体框架核心FromSql模拟测试用例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有获取存储过程调用的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).

您需要使用模拟 DbQuery< TQuery> 可查询序列,根据OP链接模拟查询提供程序(扩展了所需的任何特定模拟匹配),然后将DbQuery模拟对象分配给DbContext .Query< TQuery>()方法和DbContext DbQuery< TQuery> 属性。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆