简体   繁体   中英

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

I'm trying to fallow Adam Freeman's book "ASP .Net MVC" and create Sport Store (application from the book). This book is about classical .Net, but I'm trying to realize the application with the help of .NET Core.

In one chapter author suggests a unit test. I will describe conditions. I have a View Component 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);
    }
}

It will create something like side bar with category filter (it's on the left):

在此处输入图片说明

I'm going to highlight current category. But I want create a test before. The test is targeted to detect is category button highlighted or not.

[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)).

}

But here there is problem. The book is about classical .NET MVC. And author use Child Actions for creating snippets like side bar with some backend logic. But .NET Core don't contain this conception.

Author suggests the following line for getting ViewBag data in the test:

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

Of course, it does not work with new conception of View Components.

So my question is the next. How I can get given to ViewBag value in a some code (not in a view, but in a unit test for example) if I use View Component instance, not controller.

A few places you can check.

The ViewBag of the ViewComponent after invoke

//...

//Act
categoryNav.Invoke(categoryToSelect);

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

The ViewData of the ViewComponent after invoke

//...

//Act
categoryNav.Invoke(categoryToSelect);

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

Or the same for the view result

//...

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM