Moq Mock lambda 表达式

Moq Mock lambda expression

我正在尝试模拟执行 lambda 表达式的存储库。我要执行的方法如下所示:

public SelectListItem GetProtocolById(int protocolId)
{
    var protocol = UnitOfWork.ProtocolRepository.FindAll(s => s.PROTOCOL_ID == protocolId).FirstOrDefault();
    return new SelectListItem()
    {
        Text = protocol.USER_DEFINED_ID,
        Value = protocolId.ToString()
    };
}

我在另一个 class

中创建了一个 mockRepository
protected MockRepository mockRepository = new MockRepository(MockBehavior.Default);

我有一个 UnitOfWork 和一个协议存储库,我像这样模拟它们:

var protocolRepositoryMock = mockRepository.Create<IRepository<PROTOCOL>>();
var unitOfWorkRBMMock = mockRepository.Create<IUnitOfWorkRBM>();

IRepository 中的 FindAll 方法如下所示:

IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> where, params Expression<Func<TEntity, object>>[] includes);

而我的 IUnitOfWorkRBM 中 IRepository 的定义是这样的:

IRepository<PROTOCOL> ProtocolRepository { get; set; }

我已经尝试模拟 unitOfWorkMock 以使其能够像这样执行 lambda 表达式:

 unitOfWorkRBMMock.Setup(s => s.ProtocolRepository.FindAll(It.IsAny<Expression<Func<PROTOCOL, bool>>>()))
                .Returns(new Func<Expression<Func<PROTOCOL, bool>>, IEnumerable<PROTOCOL>>(
                expr => protocolsList.Where(expr.Compile())));

但是当我尝试调用 GetProtocolById 方法时,协议无效。

关于我在这里做错了什么有什么想法吗?

你不需要编译 - 你可以直接 Return 预期的结果。

  unitOfWorkRBMMock.Setup(s => s.ProtocolRepository.FindAll(It.IsAny<Expression<Func<PROTOCOL, bool>>>()))
                    .Returns(new List<PROTOCOL>());

提供的表达式的值可以在Returns 方法中访问。用它来过滤假列表

查看以下用于解决问题的最小示例。

[TestMethod]
public void _MyTestMethod() {
    //Arrange
    var expectedProtocolId = 1;
    var protocolsList = new List<PROTOCOL> {
        new PROTOCOL {
            PROTOCOL_ID = expectedProtocolId,
            USER_DEFINED_ID = "Some user defined Id"
        },
        new PROTOCOL {
            PROTOCOL_ID = 2,
            USER_DEFINED_ID = "Some other user defined Id"
        }
    };

    var unitOfWorkRBMMock = new Mock<IUnitOfWorkRBM>();

    unitOfWorkRBMMock
        .Setup(_ => _.ProtocolRepository.FindAll(It.IsAny<Expression<Func<PROTOCOL, bool>>>(), It.IsAny<Expression<Func<PROTOCOL, object>>[]>()))
        .Returns<Expression<Func<PROTOCOL, bool>>, Expression<Func<PROTOCOL, object>>[]>((expr, includes) => protocolsList.Where(expr.Compile()));

    var sut = new SUT(unitOfWorkRBMMock.Object);

    //Act
    var result = sut.GetProtocolById(expectedProtocolId);

    //Assert

    Assert.IsNotNull(result);
}


class SUT {
    private IUnitOfWorkRBM UnitOfWork;

    public SUT(IUnitOfWorkRBM unitOfWorkRBM) {
        this.UnitOfWork = unitOfWorkRBM;
    }

    public SelectListItem GetProtocolById(int protocolId) {
        var protocol = UnitOfWork.ProtocolRepository.FindAll(s => s.PROTOCOL_ID == protocolId).FirstOrDefault();
        return new SelectListItem() {
            Text = protocol.USER_DEFINED_ID,
            Value = protocolId.ToString()
        };
    }
}

public interface IUnitOfWorkRBM {
    IRepository<PROTOCOL> ProtocolRepository { get; set; }
}

public interface IRepository<TEntity> {
    IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> where, params Expression<Func<TEntity, object>>[] includes);
}

public class PROTOCOL {
    public int PROTOCOL_ID { get; set; }
    public string USER_DEFINED_ID { get; set; }
}