简体   繁体   English

无法通过Moq进行Cant设置模拟,以完成通用的无数任务

[英]Cant setup mock with moq for generic ienumerable task

I'm using the mocking library Moq and I'm unable to setup a mock for this signature: 我正在使用模拟库Moq,并且无法为此签名设置模拟:

Task<IEnumerable<TEntity>> GetAllAsync<TEntity>(
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = null,
            int? skip = null,
            int? take = null)
            where TEntity : class, IEntity;
}

Unit test class 单元测试课

using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using ICEBookshop.API.Factories;
using ICEBookshop.API.Interfaces;
using ICEBookshop.API.Models;
using Moq;
using SpecsFor;

namespace ICEBookshop.API.UnitTests.Factories
{
    public class GivenCreatingListOfProducts : SpecsFor<ProductFactory>
    {
        private Mock<IGenericRepository> _genericRepositorMock;

        protected override void Given()
        {
            _genericRepositorMock = new Mock<IGenericRepository>();
        }

        public class GivenRepositoryHasDataAndListOfProductsExist : GivenCreatingListOfProducts
        {
            protected override void Given()
            {
                _genericRepositorMock.Setup(
                        expr => expr.GetAllAsync<Product>(It.IsAny<Func<IQueryable<Product>>>(), null, null, null))
                    .ReturnsAsync<Product>(new List<Product>());

            }
        }
    }
}

This line of code is driving me crazy: 这行代码使我发疯:

genericRepositorMock.Setup(
                        expr => expr.GetAllAsync<Product>(It.IsAny<Func<IQueryable<Product>>>(), null, null, null))
                    .ReturnsAsync<Product>(new List<Product>());

The problem is I don't know how to setup GetAllAsync so it will compile and that it will return a list of products. 问题是我不知道如何设置GetAllAsync以便它将进行编译并返回产品列表。 The desired behavior that it returns a list of products. 它返回产品列表的所需行为。

Can anyone help me with setting up the mock with this signature? 有人可以帮我设置带有此签名的模拟吗?

First, the initial example provided has the orderBy parameter as 首先,提供的初始示例的orderBy参数为

Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy

But in the setup there is 但是在设置中

It.IsAny<Func<IQueryable<Product>>>()

which wont match the definition of the interface and cause a compilation error. 它将不匹配接口的定义并导致编译错误。

Second, use It.IsAny<> for the optional parameters to allow the mocked method to be flexible when exercising the test. 其次,对可选参数使用It.IsAny<> ,以使It.IsAny<>方法在进行测试时更加灵活。

The following simple example demonstrates 以下简单示例演示

[TestMethod]
public async Task DummyTest() {
    //Arrange
    var mock = new Mock<IGenericRepository>();
    var expected = new List<Product>() { new Product() };
    mock.Setup(_ => _.GetAllAsync<Product>(
         It.IsAny<Func<IQueryable<Product>, IOrderedQueryable<Product>>>(),
         It.IsAny<string>(),
         It.IsAny<int?>(),
         It.IsAny<int?>()
        )).ReturnsAsync(expected);

    var repository = mock.Object;

    //Act
    var actual = await repository.GetAllAsync<Product>(); //<--optional parameters excluded

    //Assert
    CollectionAssert.AreEqual(expected, actual.ToList());
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM