如何使用moq模拟ControllerContext? ERROR而嘲笑ControllerContext

问题描述:

我使用的MOQ框架和我有以下单元测试并且它与下面的错误消息“对象引用不设置为一个对象的一个​​实例,”未能在下面的代码行如何使用moq模拟ControllerContext? ERROR而嘲笑ControllerContext

viewCxt.View.Render(viewCxt, writer); 

任何人都可以指出我正确的方向,请问为什么这不通过测试?

[Test] 
public void can_call_PopulateBankTransactionWorkQueueViewInTransactionMetaDataAjaxResponseObject() 
{ 

    var transactionMetaData = new TransactionMetaDataDTO() { TransactionId = "1", FileId = "1", LockboxNumber = "0402020", DepositDate = "04.26.2011", BatchId = "1" }; 


    var request = new Mock<HttpRequestBase>(); 
    request.Setup(r => r.HttpMethod).Returns("GET"); 
    var mockHttpContext = new Mock<HttpContextBase>(); 
    mockHttpContext.Setup(c => c.Request).Returns(request.Object); 

    var controllerContext = new ControllerContext(mockHttpContext.Object, new Mock<RouteData>().Object, new Mock<ControllerBase>().Object); 

    var checkWorkQueueController = new CheckWorkQueueController(
      activeDirectorySecurityManager.Object, businessObjectAdapter, httpRequestObjectHelper.Object, invoiceRepos.Object, new HtmlHelpers()); 

    checkWorkQueueController.ControllerContext = controllerContext; 
    Assert.DoesNotThrow(() => checkWorkQueueController.PopulateBatchTreeSelectorViewInTransactionMetaDataAjaxResponseObject(transactionMetaData)); 
} 

internal void PopulateBatchTreeSelectorViewInTransactionMetaDataAjaxResponseObject(TransactionMetaDataDTO transactionMetaDataDTO) 
{ 

    var checkWorkQueueViewModel = new CheckWorkQueueViewModel(securityManager, businessObjectAdapter); 
    SetActiveFileAndLockbox(transactionMetaDataDTO, checkWorkQueueViewModel, transactionMetaDataDTO.FileId, transactionMetaDataDTO.LockboxNumber); 
    transactionMetaDataDTO.BatchTreeSelectorView = htmlHelpers.RenderViewToString(ApplicationConstants.CheckWorkQueueViewPath + ApplicationConstants.BatchTreeSelectorViewFileName, this, checkWorkQueueViewModel); 
} 

public string RenderViewToString<T>(string viewPath, ControllerBase controller, T model) 
{ 
     controller.ViewData.Model = model; 
     using (var writer = new StringWriter()) 
     { 
      var view = new WebFormView(viewPath); 
      var vdd = new ViewDataDictionary<T>(model); 
      var viewCxt = new ViewContext(controller.ControllerContext, view, vdd, new TempDataDictionary(), writer); 
      viewCxt.View.Render(viewCxt, writer); //ERROR throwing here 
      return writer.ToString(); 
     } 
} 

这里是堆栈跟踪:

at System.Web.VirtualPath.GetCacheKey() 
at System.Web.Compilation.BuildManager.GetCacheKeyFromVirtualPath(VirtualPath virtualPath, Boolean& keyFromVPP) 
at System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal(VirtualPath virtualPath, Boolean ensureIsUpToDate) 
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) 
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) 
at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound) 
at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp) 
at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp) 
at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(String virtualPath, Type requiredBaseType) 
at System.Web.Mvc.BuildManagerWrapper.System.Web.Mvc.IBuildManager.CreateInstanceFromVirtualPath(String virtualPath, Type requiredBaseType) 
at System.Web.Mvc.WebFormView.Render(ViewContext viewContext, TextWriter writer) 

一个很好的方式来调试究竟需要是对模拟设置是与MockBehavior.Strict选项来创建它。所以,

var mockHttpContext = new Mock<HttpContextBase>(); 

成为

var mockHttpContext = new Mock<HttpContextBase>(MockBehavior.Strict); 

然后,当需要从您没有设置背景下的一些测试将失败,MockException。稍后可以恢复为松散选项。

+0

不幸的是,这个错误不是由任何标准的Mocked对象产生的。 – iGanja 2013-08-01 16:44:05