使用Moq模拟UnitOfWork / GenericRepository

时间:2017-01-08 14:28:01

标签: c# unit-testing moq

我遇到了一个问题,Moq没有使用以下代码返回我所怀疑的内容:

[TestMethod]
public void GetResultReturnsAResult()
{
    var mockUnitOfWork = Arrange();
    // Arrange
    var controller = new ResultsController(mockUnitOfWork.Object);
    controller.Request = new HttpRequestMessage();
    controller.Configuration = new HttpConfiguration();

    // Act
    var response = controller.GetResult(2);

    // Assert
    Assert.IsTrue(response is OkNegotiatedContentResult<Result>);
    var contentResult = response as OkNegotiatedContentResult<Result>;
    Assert.IsNotNull(contentResult);
    Assert.IsNotNull(contentResult.Content);
    Assert.IsTrue(contentResult.Content.ID == 2);
}

[TestMethod]
public void GetResultReturnsNotFound()
{
    var mockUnitOfWork = Arrange();

    // Arrange
    var controller = new ResultsController(mockUnitOfWork.Object);
    controller.Request = new HttpRequestMessage();
    controller.Configuration = new HttpConfiguration();

    // Act
    var response = controller.GetResult(100);

    // Assert
    Assert.IsTrue(response is NotFoundResult);
    var contentResult = response as NotFoundResult;
    Assert.IsNotNull(contentResult);
}

private Mock<IUnitOfWork> Arrange()
{
    var results = new List<Result>()
    {
        new Result()
        {
            ID = 1,
            Name = "Result 1",
            Modified = new DateTime(2017, 1, 1),
            Created = new DateTime(2017, 1, 1),
            CreatedBy = "Tester 1",
            ModifiedBy = "Tester 2"
        },
        new Result()
        {
            ID = 2,
            Name = "Result 2",
            Modified = new DateTime(2017, 1, 2),
            Created = new DateTime(2017, 1, 2),
            CreatedBy = "Tester 1",
            ModifiedBy = "Tester 2"
        },
    };

    var mockUnitOfWork = new Mock<IUnitOfWork>();
    var mockResultRepository = new Mock<IGenericRepository<Result>>();

    mockResultRepository.Setup(x => x.Get(null, null, ""))
        .Returns(results);
    mockResultRepository.Setup(x => x.GetById(It.IsAny<int>()))
        .Returns((int id) => GetById(results, id));
    mockUnitOfWork.Setup(x => x.ResultRepository)
        .Returns(mockResultRepository.Object);

    return mockUnitOfWork;
}

private Result GetById(List<Result> results, int id)
{
    return results.FirstOrDefault(r => r.ID == id);
}

在这种情况下,我的TestMethods测试GetById都会抛出一个异常,其中包含以下消息:类型为&#39; System.Object []&#39;无法转换为类型&#39; System.Int32&#39;。

当我将模拟代码更改为:

mockResultRepository.Setup(x => x.Get(null, null, ""))
    .Returns(results);
mockUnitOfWork.Setup(x => x.ResultRepository)
    .Returns(mockResultRepository.Object);
mockUnitOfWork.Setup(x => x.ResultRepository.GetById(It.IsAny<int>()))
    .Returns((int id) => GetById(results, id));

GetById测试不会抛出异常,但GetResultReturnsAResult不会返回结果,因此它总是会失败。

有人能说清楚这种行为吗?

1 个答案:

答案 0 :(得分:0)

正如Eugene Podskal在评论中所建议的,我正在创建一个MCVE(download here)并遇到了解决方案。他实际上是对的,解决方案是在首先没有共享的代码中找到的。

返回

的代码
Object of type 'System.Object[]' cannot be converted to type 'System.Int32' 
自从

以来抛出此异常,

异常是正确的

GetById

需要

params object[]

作为第一个参数。