繁体   English   中英

如何使用返回类型ActionResult对动作进行单元测试 <T> ?

[英]How to unit-test action with return type ActionResult<T>?

我的问题与此非常相似:

返回类型为ActionResult时,如何对动作进行单元测试?

问题是我的问题混在通用的 ActionResult<T>类型, asyncOk(...) 我似乎无法使链接问题的答案适应一般情况。 也许我的情况有些不同。

这是一个复制品。 创建新的“ API”类型的ASP.NET Core Web应用程序。 向解决方案中添加一个新的xUnit .NET Core测试项目,该项目引用该API项目(以及任何所需的框架库)。 分别创建控制器和测试,如下所示:

public class Thing { public string Name => "Foobar"; }
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public async Task<ActionResult<Thing>> Get()
    {
        // The real "Thing" would be asynchronously retrieved from the DB
        return Ok(new Thing());
    }
}
[Fact]
public async Task Test1()
{
    var controller = new ValuesController();
    var actionResult = await controller.Get();
    Assert.NotNull(actionResult.Value);
    Assert.Equal("Foobar", actionResult.Value.Name);
}

该测试没有NotNull绿色,而是NotNull断言上失败 (或者,如果我没有该断言,它将抛出NullReferenceException )。

在调试和检查了类层次结构之后,我发现这似乎给出了预期的结果:

[Fact]
public async Task Test1()
{
    var controller = new ValuesController();
    var actionResult = await controller.Get();
    var okResult = actionResult.Result as OkObjectResult;
    var realResult = okResult?.Value as Thing;
    Assert.Equal("Foobar", realResult?.Name);
}

但这感觉就像我做错了什么。 实际上,我还有两个相关的问题:

  1. 是否有另一种惯用的方式来编写此测试,从而将所有测试折叠as演员?
  2. 为什么第一个示例可以编译,却给出运行时异常? 这里发生了什么?

使用XUnit,可以使用T t = Assert.IsType<T>(other) 这将在可能的情况下进行转换,否则将导致测试失败。

例如我做这样的事情:

IActionResult actionResult = await Controller.GetItem(id);
OkObjectResult okObjectResult = Assert.IsType<OkObjectResult>(actionResult);
Model model = Assert.IsType<Model>(okObjectResult.Value);
Assert.Equal(id, model.Id);

至于第二个问题,事情可能会在运行时引发空引用异常并正确编译。 该问题将使用C#8和非空类型解决。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM