[英]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.