Mvc 5单元测试 - 设置控制器的viewbag值

时间:2017-04-10 15:02:29

标签: c# asp.net-mvc unit-testing asp.net-mvc-5 viewbag

我有一个索引页面,其上次搜索的值可能为ViewBag。我想设置我的控制器,以便在调用我的测试系统(ViewBag)之前能够设置此ProductManagementController

索引操作

[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);
}

设置类

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;
        }
    }
}

我想设置ProductManagementController.ViewBag.SomeName = "some string"所以当我进入控制器时,我会测试该场景,但目前它是null

有人知道如何在测试之前设置控制器的ViewBag值吗?

单元测试

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);
    }
}

1 个答案:

答案 0 :(得分:2)

ViewBagViewData属性

获取其数据
public dynamic ViewBag
{
    get
    {
        if (_dynamicViewDataDictionary == null)
        {
            _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
        }
        return _dynamicViewDataDictionary;
    }
}

因此,您需要在ViewBag

中填充您想要的值才能访问它

这是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);
        }
    }

}