【问题标题】:Asp.Net Core Unit Testing Delete Method in controller控制器中的 Asp.Net Core 单元测试删除方法
【发布时间】:2019-08-08 22:59:56
【问题描述】:

我正在使用 xUnit 和 Moq 在 asp.net 核心项目中对控制器逻辑进行单元测试,但在测试删除方法时遇到了问题。我试图将来自不同教程等的一些想法放在一起,但仍然在苦苦挣扎。

我已设法测试该方法是否返回 NoContentResult 和 NotFoundResponse。我在这里缺少的是测试删除方法实际上已经从 Bygg 存储库中删除了一个项目。

在这种情况下,我在这里尝试做的是检索 Bygg 的列表,删除一个项目,然后使用 assert 检查列表现在是否只包含 2 个项目。

仅供参考:bygg = 建筑。

该项目遵循具有通用和用户特定存储库的存储库模式。

这是控制器中的删除方法:

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteBygg(int id)
{
    try
    {
        var bygg = await _byggRepository.GetByggByIdAsync(id);
        if (bygg == null)
        {
            return NotFound();
        }

        await _byggRepository.DeleteByggAsync(bygg);

        return NoContent();
    }
    catch (Exception ex)
    {
        return StatusCode(500, "Internal Server Error");
    }
}

这是测试方法:

[Fact]
public async Task DeleteBygg_ExistingIdPassed_RemovesOneItem()
{
    // Arrange
    _mockRepo.Setup(repo => repo.DeleteByggAsync(It.IsAny<Bygg>()));
    _mockRepo.Setup(repo => repo.GetAllByggAsync())
        .ReturnsAsync(GetTestBygg());

    // Act
    var actual = await _controller.GetAllBygg();
    var actual2 = actual as OkObjectResult;
    var noContentResponse = await _controller.DeleteBygg(1);


    // Assert
    var items = Assert.IsType<List<Bygg>>(actual2.Value);
    Assert.Equal(2, items.Count);
}

【问题讨论】:

  • 您可以尝试在执行测试时验证模拟是否收到预期的调用。无需获取所有和检查项目
  • 你嘲笑了DeleteByggAsync 方法,所以它实际上不会删除任何东西。也许这是错误的测试场景。您也许可以验证是否使用预期的参数调用了 DeleteByggAsync。测试实际删除的地方是在单元测试时byggRepository...
  • 您似乎还试图在一个单元测试中测试太多东西。
  • 要扩展 NKosi 所说的内容,您需要保持测试简单。在这种情况下,您实际上并不关心是否删除了某些内容,因为您的 DeleteByggAsync 测试应该验证这一点。对于控制器,您只关心调用是否被正确委派。在编写测试时,始终考虑可以删除/简化的内容
  • 仅供参考,这不是单元测试。这是集成测试。您在 Web 上下文(控制器)中,并且正在测试 EF 和数据库交互。

标签: c# unit-testing asynchronous asp.net-core moq


【解决方案1】:

由于您没有从 DeleteBygg 方法返回任何内容,您只需在测试方法中验证 await _byggRepository.DeleteByggAsync(bygg); 在您的实际方法中正确调用如下:

[Fact]
public async Task DeleteBygg_ExistingIdPassed_RemovesOneItem()
{        
    // Arrange
    var id = 1;
    _mockRepo.Setup(repo => repo.GetByggByIdAsync(id)).ReturnsAsync(new Bygg(){});
    _mockRepo.Setup(repo => repo.DeleteByggAsync(It.IsAny<Bygg>())).Returns(Task.CompletedTask);

    // Act
    await _controller.DeleteBygg(id);

    // Assert
    _mockRepo.Verify(repo => repo.DeleteByggAsync(It.IsAny<Bygg>()),Times.Once);
}

【讨论】:

  • 我想我现在对如何对控制器进行单元测试有了更好的了解。因此,如果我设法弄清楚这一点,在测试控制器逻辑时,我们正在测试调用是否正确执行。在控制器的许多其他测试中,我使用 Assert.IsType(input) 例如检查是否返回了正确的对象响应。以及检查数据是否在适用的地方返回。此外,我可能还必须对存储库进行单元测试?还是仅测试控制器就足够了?听起来像是一个反问哈哈!
  • 是的!您也必须为存储库方法编写测试方法。谢谢
猜你喜欢
  • 2018-05-01
  • 2017-03-22
  • 1970-01-01
  • 1970-01-01
  • 2017-12-12
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多