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

问题描述:

我有一个索引页,它可能有一个ViewBag上次搜索的值。我想设置我的控制器,以便我能被测打电话给我的系统之前,设置这个ViewBag值(ProductManagementControllerMvc 5单元测试 - 设置控制器的视图值

Index操作

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

这个问题解决了吗? – Nkosi

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

}