简体   繁体   English

我怎样才能返回 IQueryable<TEntity> 来自模拟对象的对象?

[英]How can I return IQueryable<TEntity> object from a mock object?

I am trying to tell a method GetAll() on a mocked object _portalUserRepositoryMock to return an object of type IQueryable<TEntity> .我试图告诉GetAll()对象_portalUserRepositoryMock上的方法GetAll()返回IQueryable<TEntity>类型的对象。 I know it is of this type because the method in the class to be tested returns this type.我知道它是这种类型,因为要测试的类中的方法返回这种类型。

I've not been able to come up with a solution.我一直想不出解决办法。 I saw this post , but had errors trying to include the library into my project.我看到了这篇文章,但在尝试将包含到我的项目中时出错。 Something about the version of Microsoft.EntityFrameworkCore - which led to more issues.关于 Microsoft.EntityFrameworkCore 版本的一些问题 - 这导致了更多问题。

What I did to get this error was:我为得到这个错误所做的是:

_portalUserRepositoryMock = Substitute.For<IPortalUserRepository>();
_portalUserRepositoryMock.GetAll().Returns(fakeQueryablePUser.AsQueryable());

The class under test uses the repository like this:被测类使用这样的存储库:

var portal = await _portalUserRepository.GetAll().Include(p => 
p.Portal).Where(p => p.UserId == user.Id && p.Portal.PortalType == 
dto.PortalType).FirstOrDefaultAsync();

and the GetAll() method is: GetAll()方法是:

        public IQueryable<TEntity> GetAll()
    {
        try
        {
            return DbContext.Set<TEntity>().AsNoTracking();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

I get this error:我收到此错误:

Message: System.InvalidOperationException : The provider for the source IQueryable doesn't implement IAsyncQueryProvider.消息:System.InvalidOperationException:源 IQueryable 的提供程序未实现 IAsyncQueryProvider。 Only providers that implement IEntityQueryProvider can be used for Entity Framework asynchronous operations.只有实现 IEntityQueryProvider 的提供程序才能用于实体框架异步操作。

I reckon I'm getting this error because of the FirstOrDefaultAsync() that is being used.我认为我收到此错误是因为正在使用FirstOrDefaultAsync() Just have no idea on how to resolve it.只是不知道如何解决它。

Edit : I have now been able to add the MockQueryable library to my test project (by using version 1.0.4 and not the latest 1.1.0 ).编辑:我现在已经能够将 MockQueryable 库添加到我的测试项目中(使用版本 1.0.4 而不是最新的 1.1.0 )。 I have followed the steps, as shown below:我已按照步骤操作,如下所示:

        var fakePortalUser = new PortalUser()
        {
            PortalId = new Guid()
        };

        var fakeQueryablePUser = new List<PortalUser>
        {
            fakePortalUser
        }.AsQueryable().BuildMock();

Last step is now to use GetQueryable() .最后一步是现在使用GetQueryable() Which I try to use here:我尝试在这里使用:

_portalUserRepositoryMock.GetAll().GetQueryable().Returns(fakeQueryablePUser);

But I get the red squigly line under the GetQueryable() method call.但是我在GetQueryable()方法调用下得到了红色波浪线。 So code won't compile.所以代码不会编译。

The initial issue is as you suspected with FirstOrDefaultAsync .最初的问题是你怀疑FirstOrDefaultAsync That extension expects the queryable to also have a IAsyncQueryProvider in order to match async EF which the mock wont be by default.该扩展希望可查询对象也具有IAsyncQueryProvider以匹配模拟默认情况下不会的异步 EF。

Remove .GetQueryable() as you do not need it.删除.GetQueryable()因为您不需要它。 That member came from one of the samples to demonstrate how to use the mock library.该成员来自演示如何使用模拟库的示例之一。

Also make sure the fake data has data in it that will match the predicate in the Where .还要确保假数据中包含与Where中的谓词匹配的数据。

.Where(p => p.UserId == user.Id && p.Portal.PortalType == dto.PortalType)

FirstOrDefault will return null if there are no elements to enumerate.如果没有要枚举的元素, FirstOrDefault将返回null

And if the data does not satisfy the filter you will get back null by default.如果数据不满足过滤器,默认情况下您将返回null

You dont, IQueryable<T> is an implementation detail handled by Entity Framework / Core.你不知道, IQueryable<T>是由实体框架/核心处理的实现细节。 Unless your business logic actually creates an implementation of IQueryable<T> then you want to return a mock stub object.除非您的业务逻辑实际上创建了IQueryable<T>的实现,否则您希望返回一个模拟存根对象。

ie (Note that this uses the library Moq to mock the objects as im not sure what you're using and the implementation may vary.)即(请注意,这使用库Moq来模拟对象,因为我不确定您正在使用什么并且实现可能会有所不同。)

_mockedEntityQuery = new Mock<IQueryable<T>>();
_portalUserRepositoryMock = Substitute.For<IPortalUserRepository>();
_portalUserRepositoryMock.GetAll().Returns(_mockedEntityQuery.Object);

If you return an instance of IQueryable<T> you would also be testing that implementation which will have already been done by the EF unit tests.如果您返回IQueryable<T>的实例,您还将测试该实现,该实现已经由 EF 单元测试完成。 Unit tests should only test the code that is within the scope of the unit.单元测试应该只测试单元范围内的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将字符串转换为TEntity并使用此TEntity对象? - How can I convert string to TEntity and use this TEntity object? 创建表达式<Func<TEntity,object> &gt; 动态调用聚合到 IQueryable<TEntity> - Create Expression<Func<TEntity,object>> dynamically and call Aggregate to IQueryable<TEntity> 如何将另一个对象添加到已定义的IQueryable对象? - how can i add another object to an already defined IQueryable object? 为什么我不能投射EntityCollection <TEntity> 到ICollection <Object> ? - Why can't I cast EntityCollection<TEntity> to ICollection<Object>? 从EF代理对象返回IQueryable - Return IQueryable from EF proxy object 从LINQ IQueryable对象返回string []? - return string[] from LINQ IQueryable object? C# - 如何使用Where Like%搜索IQueryable对象 - C# - How can I search in a IQueryable object with Where Like % 如何将IQueryable表达式对象转换为LINQ表达式? - How can I convert IQueryable expression object into LINQ expression? 如何将列添加到IQueryable对象并修改其值 - how can I add a column to IQueryable object and modify its values 我可以通过IQueryable <Foo> 进入IQueryable <IFoo> 如果对象实现了该接口? - can i pass in IQueryable<Foo> into IQueryable<IFoo> if the object implements that interface?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM