首页 > 解决方案 > c# web api中的起订量单元测试

问题描述

我正在尝试在 asp.net core 2 中测试一种 web api 方法。

网页接口

方法:

public IActionResult Delete(int id)
{
    try
    {
        var success = sportsService.DeleteSport(id);

        if (!success)
        {
            return new NotFoundResult();
        }
        return new OkResult();
    }
    catch (Exception e)
    {
        return new StatusCodeResult(400);
    }
}

单元测试部分:

private Mock<ISportsService> mockService;

[SetUp]
public void Setup()
{
    mockService.SetupSequence(x => x.DeleteSport(It.IsAny<int>())).
        Returns(true). // OkResult();
        Returns(false). // NotFoundResult()
        Throws(new Exception()); //Exception
}

测试方法如下所示。我对这种方法不清楚的是,测试该方法的正确方法是什么?

[Test]
public void TestStrategyControllerWithDelete()
{
    var result = controller.Delete(STRAT_ID);
    var okResult = result as ObjectResult;
    Assert.AreEqual(HttpStatusCode.NotFound, okResult.StatusCode);
    Assert.AreEqual(HttpStatusCode.OK, okResult.StatusCode);
    Assert.AreEqual(400, okResult.StatusCode);
}

我确定为 null !并且无法获得 okResult.StatusCode

标签: c#unit-testingmoq

解决方案


您正在将模拟设置为:

  • true首次调用时返回
  • false第二次调用时返回。
  • new Exception()再次调用时抛出。

但是,在您的测试中,您只调用一次(var result = controller.Delete(STRAT_ID);因此您的 Moq 将始终返回true

编写 3 个单独的测试,而不是一个:

[Test]
public void Delete_ReturnsOkResult_IfDeleteSuccess()
{
  const int deleteId = 1234;
  mockService.Setup(x => x.DeleteSport(deleteId)).Returns(true);

  var result = controller.Delete(deleteId);

  Assert.IsInstanceOf<OkResult>(result);
}

单元测试应该是独立的。它们应该能够以任何顺序运行而不会相互干扰。但是,通过SetupSequence()[SetUp]步骤中配置 a,您至少将其中 3 个捆绑在一起并强制对它们下达订单。

编辑:对于“并且无法获得 okResult.StatusCode”* 更新问题

您将返回OKResultNotFoundResultStatusCodeResult。这些都不是从 ObjectResult 继承的,这就是它为 NULL 的原因。我已经更新了我的代码示例以检查显式类型 ( OKResult),这需要针对每个测试用例进行更新。

如果您想检查单个 StatusCodes,您可以将其转换为 a StatusCodeResult,因为所有返回类型都可以转换为此。


推荐阅读