从 View Component 实例获取传递的 ViewBag 数据(例如在测试中)

Getting passed ViewBag data from a View Component instance (for example in tests)

我正在尝试利用 Adam Freeman 的书 "ASP .Net MVC" 并创建 Sport Store(书中的应用程序)。这本书是关于 classical .Net 的,但我正在尝试借助 .NET Core 实现应用程序。

在一章中,作者建议进行单元测试。我将描述条件。我有一个视图组件 class:

public class CategoryNav : ViewComponent
{
    private readonly IProductRepository _repository;

    public CategoryNav(IProductRepository repository)
    {
        _repository = repository;
    }

    public IViewComponentResult Invoke(string currentCategory)
    {
        ViewBag.SelectedCategory = currentCategory;

        var categories = _repository.Products
            .Select(x => x.Category)
            .Distinct()
            .OrderBy(x => x);

        return View(categories);
    }
}

它将创建类似带有类别过滤器的边栏(在左侧):

我要突出显示当前类别。但我想先创建一个测试。 该测试旨在检测类别按钮是否突出显示。

[Test]
public void Indicate_Selected_Category()
{
    Mock<IProductRepository> mock = new Mock<IProductRepository>();

    mock.Setup(m => m.Products).Returns(new Product[]
    {
        new Product{ Id = 1, Name = "P1", Category = "Apples"}, 
        new Product{ Id = 4, Name = "P2", Category = "Oranges"}, 
    });

    CategoryNav categoryNav = new CategoryNav(mock.Object);

    var categoryToSelect = "Appless";

    // How to get here ViewBag data ???
 //    var result = ((ViewViewComponentResult)categoryNav.Invoke(categoryToSelect)).

}

但是这里有问题。这本书是关于 classical .NET MVC 的。并且作者使用子操作来创建带有一些后端逻辑的边栏等片段。但是.NET Core 不包含这个概念。

作者建议在测试中使用以下行获取 ViewBag 数据:

string res = objectOfController.<name_of_childe_action>.ViewBag.<data_that_I_need>

当然,它不适用于视图组件的新概念。

所以我的问题是下一个。如果我使用 View Component 实例而不是控制器,我如何在某些代码中(不是在视图中,而是在单元测试中)获得 ViewBag 值。

您可以检查几个地方。

调用后ViewComponent的ViewBag

//...

//Act
categoryNav.Invoke(categoryToSelect);

// Assert
Assert.AreEqual(categoryToSelect, categoryNav.ViewBag.SelectedCategory);

调用后ViewComponent的ViewData

//...

//Act
categoryNav.Invoke(categoryToSelect);

// Assert    
Assert.AreEqual(categoryToSelect, categoryNav.ViewData["SelectedCategory"]);

或查看结果相同

//...

//Act
var result = (ViewViewComponentResult)categoryNav.Invoke(categoryToSelect);

// Assert    
Assert.AreEqual(categoryToSelect, result.ViewData["SelectedCategory"]);