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

编程入门 行业动态 更新时间:2024-10-19 13:28:06
本文介绍了如何使用返回类型ActionResult< T>对动作进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我的问题与这个问题非常相似:

My question is very similar to this one:

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

问题是我的问题混入了通用 ActionResult< T> 类型, async 和 Ok(..).我似乎无法使链接问题的答案适应一般情况.也许我的情况略有不同.

The problem is that my question mixes in the generic ActionResult<T> type, async, and Ok(...). I can't seem to adapt linked question's answer to the generic situation. Or possibly my scenario is subtly different.

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

Here's a repro. Create new ASP.NET Core Web Application of "API" type. Add a new xUnit .NET Core test project to the solution, that references the API project (as well as any needed framework libs). Create the controller and tests like this, respectively:

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 断言上失败了(或者,如果我没有该断言,它会抛出 NullReferenceException ).

Instead of turning green, this test fails on the NotNull assertion (or, if I would not have that assertion, it throws a NullReferenceException).

在调试并检查了类层次结构之后,我发现这似乎可以达到预期的结果:

After debugging and inspecting the class hierarchy, I found that this seems to give the desired results:

[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); }

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

But this feels like I'm doing something wrong. Practically, I'm left with two related questions:

  • 是否有另一种惯用的方式编写此测试,从而将所有那些 as 强制转换折叠起来?
  • 第一个示例为什么要编译,却给出运行时异常?这是怎么回事?
  • 推荐答案

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

    With XUnit, you can use T t = Assert.IsType<T>(other). That will do the casting if possible, but otherwise it will cause the test to fail.

    例如,我做这样的事情:

    For instance I do something like this:

    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和非空类型解决.

    As for your 2nd question, things can throw null reference exceptions at runtime and compile correctly. That problem will be solved with C# 8 and non-nullable types.

    更多推荐

    如何使用返回类型ActionResult&lt; T&gt;对动作进行单元测试?

    本文发布于:2023-11-14 15:18:09,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1587779.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:如何使用   单元测试   动作   类型   amp

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!