How to unit test a ViewBag in ASP.NET Core?
While testing unit apps for ASP.NET Core, I realized I was ViewData
available with ViewResult
, but ViewBag
not.
My : 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);
}
}
My 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;
}
}
Question 1: Why is there no property ViewBag
in ViewResult
when the ASP.NET MVC version of the class ViewResult
clearly has one ( MSDN )?
Question 2: How should I test ViewBag
when I don't have access to it?
source to share
Question 1: Another mystery for me. More like a question for Core developers.
Question 2:
"A property
ViewBag
is a wrapper aroundViewData
that dynamic view of this collection. It is not a separate collection." - ASP.NET Core Documents
So this is one object. Since there is ViewResult
no property in it ViewBag
(reminder - we're talking about the Core version here), refer to it in word style ViewData
:
var questSelectListVB = Assert.IsAssignableFrom<SelectList>(viewResult.ViewData["QuestSelectList"]);
source to share