如何在 ASP.NET Core 中对 ViewBag 进行单元测试?
How to unit test ViewBag in ASP.NET Core?
在为 ASP.NET 核心应用程序编写单元测试时,我意识到 ViewData
可以从 ViewResult
访问,但 ViewBag
不能。
我的HomeController
:
public class HomeController : Controller
{
private readonly IHeroRepository _heroItems;
private readonly IQuestRepository _questItems;
public HomeController(
IHeroRepository heroItems,
IQuestRepository questItems)
{
_heroItems = heroItems;
_questItems = questItems;
}
[HttpGet]
public async Task<IActionResult> Index()
{
var recentHeroesVM = await _heroItems.GetRecentHeroesAsync(2);
ViewBag.QuestSelectList = await _questItems.GetSelectListAsync();
return View(recentHeroesVM);
}
}
我的测试class:
public class HomeController_Index
{
[Fact]
public async Task Index_ReturnsAViewResult_WithAListOfRecentHeros()
{
// Arrange
var mockHeroRepo = new Mock<IHeroRepository>();
var mockQuestRepo = new Mock<IQuestRepository>();
var recentHerosCount = 2;
mockHeroRepo.Setup
(
repo => repo.GetRecentHerosAsync(recentHerosCount))
.Returns(Task.FromResult(GetTestItems())
);
var controller = new HomeController(mockHeroRepo.Object, mockQuestRepo.Object);
// Act
var result = await controller.Index();
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
// No definition error below.
var questSelectListVB = Assert.IsAssignableFrom<SelectList>(
viewResult.ViewBag.QuestSelectList);
}
private IEnumerable<HeroViewModel> GetTestItems()
{
var items = new List<HeroViewModel>
{
new HeroViewModel
{
Name = "First Hero",
},
new HeroViewModel
{
Name = "Second Hero",
},
};
return items;
}
}
问题1:为什么在ASP.NETMVC版本ViewResult
中没有ViewBag
属性ViewResult
class 明明有一个(MSDN)?
问题 2: 当我无法访问 ViewBag
时,我应该如何测试它?
问题一:对我来说还是个谜。更像是核心开发人员的问题。
问题二:
"The ViewBag
property is a wrapper around ViewData
that provides a dynamic view over that collection. It is not a separate collection." - ASP.NET Core Docs
所以它是一个对象。由于 ViewResult
中没有 ViewBag
属性 (提醒 - 我们在这里谈论的是 Core 版本),因此在 ViewData
字典样式中访问它:
var questSelectListVB = Assert.IsAssignableFrom<SelectList>(viewResult.ViewData["QuestSelectList"]);
在为 ASP.NET 核心应用程序编写单元测试时,我意识到 ViewData
可以从 ViewResult
访问,但 ViewBag
不能。
我的HomeController
:
public class HomeController : Controller
{
private readonly IHeroRepository _heroItems;
private readonly IQuestRepository _questItems;
public HomeController(
IHeroRepository heroItems,
IQuestRepository questItems)
{
_heroItems = heroItems;
_questItems = questItems;
}
[HttpGet]
public async Task<IActionResult> Index()
{
var recentHeroesVM = await _heroItems.GetRecentHeroesAsync(2);
ViewBag.QuestSelectList = await _questItems.GetSelectListAsync();
return View(recentHeroesVM);
}
}
我的测试class:
public class HomeController_Index
{
[Fact]
public async Task Index_ReturnsAViewResult_WithAListOfRecentHeros()
{
// Arrange
var mockHeroRepo = new Mock<IHeroRepository>();
var mockQuestRepo = new Mock<IQuestRepository>();
var recentHerosCount = 2;
mockHeroRepo.Setup
(
repo => repo.GetRecentHerosAsync(recentHerosCount))
.Returns(Task.FromResult(GetTestItems())
);
var controller = new HomeController(mockHeroRepo.Object, mockQuestRepo.Object);
// Act
var result = await controller.Index();
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
// No definition error below.
var questSelectListVB = Assert.IsAssignableFrom<SelectList>(
viewResult.ViewBag.QuestSelectList);
}
private IEnumerable<HeroViewModel> GetTestItems()
{
var items = new List<HeroViewModel>
{
new HeroViewModel
{
Name = "First Hero",
},
new HeroViewModel
{
Name = "Second Hero",
},
};
return items;
}
}
问题1:为什么在ASP.NETMVC版本ViewResult
中没有ViewBag
属性ViewResult
class 明明有一个(MSDN)?
问题 2: 当我无法访问 ViewBag
时,我应该如何测试它?
问题一:对我来说还是个谜。更像是核心开发人员的问题。
问题二:
"The
ViewBag
property is a wrapper aroundViewData
that provides a dynamic view over that collection. It is not a separate collection." - ASP.NET Core Docs
所以它是一个对象。由于 ViewResult
中没有 ViewBag
属性 (提醒 - 我们在这里谈论的是 Core 版本),因此在 ViewData
字典样式中访问它:
var questSelectListVB = Assert.IsAssignableFrom<SelectList>(viewResult.ViewData["QuestSelectList"]);