【问题标题】:How do I unit test an action that returns a ToList如何对返回 ToList 的操作进行单元测试
【发布时间】:2020-01-05 19:02:01
【问题描述】:

您好,我正在尝试为此控制器方法运行一些测试,但我正在努力测试视图,这是我的控制器类。

public class StockController : Controller
{
    private readonly IStockService _stockService;

    public StockController(IStockService stockService)
    {
        _stockService = stockService;
    }

    // GET: Stock
    public async Task<IActionResult> Index()
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        IEnumerable<StockDto> stocks = null;
        try
        {
            stocks = await _stockService.GetStockAsync();
        }
        catch (HttpRequestException)
        {
            stocks = Array.Empty<StockDto>();
        }
        return View(stocks.ToList());
    }
}

这是 Stock Controller 的 MS 测试项目的测试方法,我的 ArrangeAct 工作正常,但对于 Asserts 'ViewResult' 上有一条红线,我不知道为什么。

[TestMethod]
public async Task ReturnIndexMethod()
{
    //Arrange
    var controller = new StockController(new FakeStockService());
    //Act
    var result = await controller.Index(); 
    //Assert
    Assert.IsNotNull(result);
    var AResult = result as ViewResult;
    Assert.IsNotNull(AResult);
    var stockResult = AResult.Value as IEnumerable<StockDto>;
    Assert.IsNotNull(stockResult);

}

这里还有FakeStockService,它将提供模拟测试数据,以防人们需要查看它。

public class FakeStockService : IStockService
{
    private readonly IEnumerable<StockDto> _stock = new List<StockDto>
    {
        new StockDto { Id = 1, Name = "asfdaf", Description = "afsdfsfdsda", Price = 5000 }
    };

    public Task<IEnumerable<StockDto>> GetStockAsync()
    {
        return Task.FromResult(_stock);
    }
}

任何帮助或建议将不胜感激,在尝试了其他所有方法后,我只是不知所措。

【问题讨论】:

  • 除非那是一个错字,否则视图结果应该有一个模型属性,而不是像你在那里的值。在我看来,其他一切都很好。错误信息是什么?可能测试缺少命名空间以访问该 View Result 类型。
  • 我没有错误,但我将其更改为 var stockResult = AResult.ViewData.Model as IEnumerable;这似乎效果更好,ViewResult 有一条红线,它告诉我将其更改为“as Microsoft.AspNetCore.Mvc.ViewResult;”相反,但我不确定为什么,这似乎也不起作用。并感谢您回复 Nkosi。

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


【解决方案1】:

也许测试缺少命名空间以便访问 ViewResult 类型。

using Microsoft.AspNetCore.Mvc;
//...

另外,除非是拼写错误,否则视图结果应该有一个 Model 属性,而不是像你那里那样的 Value

[TestMethod]
public async Task ReturnIndexMethod()
{
    //Arrange
    var controller = new StockController(new FakeStockService());

    //Act
    var result = await controller.Index(); 

    //Assert
    Assert.IsNotNull(result);
    var view = result as ViewResult;
    Assert.IsNotNull(view);
    var stockResult = view.Model as IEnumerable<StockDto>;
    Assert.IsNotNull(stockResult);
}

在我看来,测试中的其他一切都很好。

然而,控制器操作似乎正在通过 GET 请求访问模型状态。显示的当前示例没有任何明显需要使用模型状态,因此我建议删除它

public async Task<IActionResult> Index() {
    IEnumerable<StockDto> stocks = null;
    try {
        stocks = await _stockService.GetStockAsync();
    }
    catch (HttpRequestException) {
        stocks = Array.Empty<StockDto>();
    }
    return View(stocks.ToList());
}

【讨论】:

  • 谢谢,这很有帮助,但奇怪的是 ViewResult 仍然有错误,而且我确实有你建议的 mvc 命名空间,最新的包。 VS告诉我把它改成“as Microsoft.AspNetCore.Mvc.ViewResult;”它似乎有效,但很奇怪!我删除了ModelRequest,谢谢你的建议,不知道为什么我有它,我只是习惯了。我还把它改成了 Model 而不是 Value。
猜你喜欢
  • 1970-01-01
  • 2013-11-25
  • 2019-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2020-09-28
  • 2014-05-10
相关资源
最近更新 更多