Mvc 5 Tests - Set Controller Summing Value

I have an index page that can have a ViewBag

last search value . I want to customize my controller so I can set this value ViewBag

before calling my system under test ( ProductManagementController

)

Index action

[HttpPost]
public async Task<ActionResult> Index(ProductManagementVm postedVm)
{
    // Reset pagination if new search
    if (postedVm.BookSearch != ViewBag.lastSearch)
    {
        postedVm.Page = 1;
    }

    var httpResponseMessage = await_httpService.GetAsync(_urlConfigurations.GetProductList);

    var vm = _productFactory.BuildProductManagementVm(
                    await Task.Run(() => httpResponseMessage.Content.ReadAsStringAsync()), postedVm);


    vm.BookSearch = postedVm.BookSearch;

    if (string.IsNullOrEmpty(postedVm.BookSearch))
    {
        postedVm.BookSearch = string.Empty;
    }

    ViewBag.lastSearch = postedVm.BookSearch;
    return View(vm);
}

      

Installation class

using System.ComponentModel.DataAnnotations;
using System.Net.Http;
using System.Web.Mvc;
using ICEBookshop.MVC.App.Controllers;
using ICEBookshop.MVC.App.Interfaces;
using ICEBookshop.MVC.App.Interfaces.Factories;
using ICEBookshop.MVC.App.Models;
using ICEBookshop.MVC.App.Models.ViewModels;
using Moq;
using SpecsFor;

namespace ICEBookshop.MVC.App.Tests.Controllers.ProductManagement
{
    public class BaseGiven : SpecsFor<ProductManagementController>
    {
        protected Mock<IHttpService> HttpServiceMock = new Mock<IHttpService>();
        protected Mock<IProductFactory> ProductFactoryMock = new Mock<IProductFactory>();
        protected Mock<IUrlConfigurations> UrlConfigurationsMock = new Mock<IUrlConfigurations>();
        protected Mock<IJsonValidator> JsonValidatorMock = new Mock<IJsonValidator>();
        protected ProductManagementController ProductManagementController;
        protected HttpResponseMessage HttpResponseMessage;
        protected string JsonContent;
        protected bool IsModelStateValid;  

        protected ActionResult ActionResult;
        protected RedirectToRouteResult RedirectToRouteResult;
        protected ViewResult ViewResult;
        protected ProductManagementVm ProductManagementVm;
        protected ProductViewModel ProductViewModel;   

        protected void BaseGivenSetup()
        {
            ProductManagementController = new ProductManagementController(HttpServiceMock.Object,
                ProductFactoryMock.Object, UrlConfigurationsMock.Object, JsonValidatorMock.Object);

            SUT = ProductManagementController;
        }
    }
}

      

I would like to install ProductManagementController.ViewBag.SomeName = "some string"

, so when I enter the controller I am testing this scenario, but at the moment it is null

.

Does anyone know how to set a ViewBag

controller value before testing it?

Unit test

public class WhenServiceReturnProductsAndViewBagHasSearchString : GivenGoingToIndexActionInProductsManagement
{
    protected override void When()
    {
        HttpResponseMessage = new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK,
            Content = new StringContent("some string content from the service")
        };

        HttpServiceMock.Setup(expr => expr.GetAsync(It.IsAny<string>())).ReturnsAsync(HttpResponseMessage);

        ProductFactoryMock.Setup(
                expr => expr.BuildProductManagementVm(It.IsAny<string>(), It.IsAny<ProductManagementVm>()))
            .Returns(new ProductManagementVm());

        // This doesn't work :(
        SUT.ViewBag.LastSearch = "Hey I'm a search string :D";

        BaseGivenSetup();

        ActionResult = SUT.Index(new ProductManagementVm()).Result;
        ViewResult = (ViewResult)ActionResult;
        ProductManagementVm = (ProductManagementVm)ViewResult.Model;
    }

    [Test]
    public void ThenActionResultIsNotNull()
    {
        Assert.IsNotNull(ActionResult);
    }

    [Test]
    public void ThenAViewResultIsNotNull()
    {
        Assert.IsNotNull(ViewResult);
    }

    [Test]
    public void ThenProductManagementVmIsNotNull()
    {
        Assert.IsNotNull(ProductManagementVm);
    }
}

      

+3


source to share


1 answer


ViewBag gets its data from propertyViewData

public dynamic ViewBag
{
    get
    {
        if (_dynamicViewDataDictionary == null)
        {
            _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
        }
        return _dynamicViewDataDictionary;
    }
}

      

So you need to fill in the value you want in order to be able to access it in ViewBag



Here is the POC

[TestClass]
public class ViewBagTests {
    [TestMethod]
    public void ViewBag_ShouldBe_PrePopulated() {
        //Arrange
        var SUT = new TargetController();

        var expected = "Hey I'm the old search string :D";

        SUT.ViewData["LastSearch"] = expected;

        //Act
        var actual = SUT.Index() as ViewResult;

        //Assert
        Assert.AreEqual(expected, actual.Model);
    }

    class TargetController : Controller {
        public ActionResult Index() {
            var previous = ViewBag.LastSearch;
            return View((object)previous);
        }
    }

}

      

+2


source







All Articles