我试图使用Moq模拟存储库。我发现了类似问题的多个问题,但我发现没有一个能够解决我遇到的问题。
所以我使用了可以下载here的存储库。更具体地说,可以查看存储库本身here,并且可以看到我使用的查询扩展名here。
这就是我的测试设置:
// A List<> of fakes.
this.containers = Builder<Container>.CreateListOfSize(10).Build();
// Here I'm trying to set up the mock object for the query.
this.containerRepoMock.Setup(p => p.
Query(It.IsAny<Expression<Func<Container, bool>>>())
.Include(It.IsAny<Expression<Func<Container, object>>>())
.Select())
.Returns((Expression<Func<Container, bool>> query, Expression<Func<Container, object>> include) =>
this.containers.AsQueryable().Where(query).Include(include));
// Tell the service to use the mock repository.
this.containerService = new ContainerService(mockUnitOfWork.Object);
这是我尝试测试的服务方法:
public ContainerDto GetContainerAndItsCategories(int containerId)
{
var entity = Repository
.Query(w => w.ContainerId == containerId)
.Include(c => c.Categories)
.Select();
var output = Mapper.EntityToDto(entity.SingleOrDefault());
return output;
}
每当我尝试在我的测试中使用模拟存储库运行此服务方法时,它会抛出异常&#34; System.Reflection.TargetParameterCountException:参数计数不匹配。&#34;
我尝试在模拟设置中为.Returns()方法添加额外的对象参数,但没有成功。它总是抛出相同的异常。从我读过的内容来看,Moq在测试表达式方面有些局限,但是我已经看到了人们在成功时做类似事情的例子。
由于Include()和Query()方法返回一个IQueryFluent()实例而不是直接表达式,我试图在Moq return()方法中使用QueryFluent()类但是还没有能够做到它成功地使用了queryable(编译错误)。
非常感谢任何帮助,真的希望能够使用单元测试来正确测试。
编辑 - 我所看过的类似问题
答案 0 :(得分:2)
问题在于这一行:
this.containerRepoMock.Setup(p => p.
Query(It.IsAny<Expression<Func<Container, bool>>>())
.Include(It.IsAny<Expression<Func<Container, object>>>())
.Select())
你不能(就我的Moq知识而言)在一次Setup
调用中设置一组方法。此外,在这一行:
.Returns((Expression<Func<Container, bool>> query, Expression<Func<Container, object>> include) =>
this.containers.AsQueryable().Where(query).Include(include));
您告诉Moq(在Setup
调用中)期望使用两个参数(query
和include
)调用单个方法并将其传递给Returns
lambda在这里。显然情况并非如此:您调用了两个单参数方法,因此Moq抛出了参数不匹配异常。
您需要将其分解为其组件并设置模拟返回值。此外,由于您希望使用Expression
对象,因此您需要将这些对象保存在最后才能使用。例如:
var containerRepoMock = new Mock<IRepositoryAsync<Container>>();
var queryFluentQueryMock = new Mock<IQueryFluent<Container>>();
var queryFluentIncludeMock = new Mock<IQueryFluent<Container>>();
Expression<Func<Container, bool>> query = null;
containerRepoMock.Setup(p => p.Query(It.IsAny<Expression<Func<Container, bool>>>()))
.Callback<Expression<Func<Container, bool>>>(q => query = q)
.Returns(queryFluentQueryMock.Object);
Expression<Func<Container, object>> include = null;
queryFluentQueryMock.Setup(p => p.Include(It.IsAny<Expression<Func<Container, object>>>()))
.Callback<Expression<Func<Container, object>>>(i => include = i)
.Returns(queryFluentIncludeMock.Object);
queryFluentIncludeMock.Setup(p => p.Select())
.Returns(containers.AsQueryable().Where(query).Include(include));
请原谅任何编译错误,我没有下载你链接的库来试试这个