从 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"]);
我正在尝试利用 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"]);