簡體   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