During writing unit tests for ASP.NET Core application I realized that the ViewData
is accessable from ViewResult
but ViewBag
is 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 testing 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 there is no ViewBag
property in ViewResult
when in the ASP.NET MVC version of ViewResult
class there is clearly one (MSDN)?
Question 2: How I am supposed to test the ViewBag
when I have no access to it?
viewResult
? Have you tried to specify type explicitlyViewResult viewResult = Assert.IsType<ViewResult>(result);
(and likely get compile time error) ? – Bedspring