【问题标题】:Mock IEnumerable<T> is returning null模拟 IEnumerable<T> 返回 null
【发布时间】:2019-08-22 01:20:28
【问题描述】:

我正在使用 XUnit 单元测试在 .NET Core 2.1 中测试我的 API 控制器。我正在使用 MOQ 来模拟我的接口存储库。在我进行设置时调试我的单元测试,它在到达控制器之前仍然为空。

我尝试使用ReturnsReturnsAsync 构造结果。使用单独的函数返回列表或IEnumerable&lt;T&gt;

控制器

[HttpGet]
public async Task<IActionResult> GetPendingApprovals()
{
    var user = _serviceRepository.GetUserName(User);
    var userId = await _serviceRepository.GetUserID(user);

    var result = await _requestRepository.GetPendingApprovalsByApprover(userId);

    if (!result.Any()) return NoContent();

    return Ok(result);

}

测试

private Mock<IServiceRepository> mockServiceRepo;
private Mock<IRequestRepository> mockRequestRepo;
private ApprovalController controller;


public ApproverControllerTests()
{
    mockServiceRepo = new Mock<IServiceRepository>();
    mockRequestRepo = new Mock<IRequestRepository>();
    ILogger<ApprovalController> mockLoggerRepo = Mock.Of<ILogger<ApprovalController>>();
    controller = new ApprovalController(mockRequestRepo.Object, mockServiceRepo.Object, mockLoggerRepo);
}

[Fact]
public async Task GetPendingApprovals_HasPending_ReturnsResultAsync()
{
     // Arrange
     var mockRequests = new List<Request>
     {
         new Request { Id = 1,
             PONumber = "ABC0001",
             RequestorId = 1,
             SubmitDate = new DateTime(),
             ApproverId = 2,
             StatusId = 1,
             Split = false,
             VendorId1 = 1,
             Remarks = "
         },
         new Request { Id = 2,
             PONumber = "ABC0002",
             RequestorId = 1,
             SubmitDate = new DateTime(),
             ApproverId = 2,
             StatusId = 1,
             Split = false,
             VendorId1 = 1,
             Remarks = "
        }
     };
     mockServiceRepo.Setup (repo => repo.GetUserID ("pstaley").Returns (Task.FromResult (1);
     //var pending = mockRequests.AsEnumerable();
     mockRequestRepo.Setup (repo => repo.GetPendingApprovalsByApprover (1).Returns (Task.FromResult<IEnumerable<Request>> (mockRequests);
     // Act
     var result = await controller.GetPendingApprovals();

    // Assert
    var actionResult = Assert.IsType<OkObjectResult>(result);
    //Assert.Equal(mockRequests, actionResult);

}

调试测试本身,mockRequestnull,因此当它进入控制器时,它会遇到 null 检查并且不返回任何内容响应。

【问题讨论】:

  • User 很可能是 null,因为我没有看到任何设置,因此模拟的期望不匹配,默认情况下返回 null。
  • 为什么不使用ReturnsAsync,这样你就可以避开Task.FromResult
  • 看来问题在于您没有设置 GetUserName 以返回 "pstaley"
  • 就是这样。谢谢你。我在想这并不重要,因为所做的只是拉入我手动传递给第二个调用的用户 ID。经验教训。

标签: c# .net-core moq xunit.net


【解决方案1】:

User 很可能是 null,因为我没有看到任何设置,GetUserName 也没有设置为执行任何操作,因此它也会为空。

因此模拟的期望不匹配,默认返回 null。

It.IsAny&lt;string&gt;() 放松对GetUserID 的期望以获得预期的行为。

[Fact]
public async Task GetPendingApprovals_HasPending_ReturnsResultAsync() {
    // Arrange
    var mockRequests = getUsers();
    var userId = 1;
    mockServiceRepo
        .Setup(repo => repo.GetUserID(It.IsAny<string>()))
        .ReturnsAsync(userId);

    mockRequestRepo
        .Setup(repo => repo.GetPendingApprovalsByApprover(userId))
        .ReturnsAsync(mockRequests);

    // Act
    var result = await controller.GetPendingApprovals();

    // Assert
    var actionResult = Assert.IsType<OkObjectResult>(result);

    //...

}

List<Request> getUsers() {
    //... omitted for brevity
}

【讨论】:

    猜你喜欢
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2021-12-24
    相关资源
    最近更新 更多