我正在尝试测试一些依赖于ControllerContext.RouteData中的Values属性的应用程序逻辑.
到目前为止我有
// Arrange
var httpContextMock = new Mock<HttpContextBase>(MockBehavior.Loose);
var controllerMock = new Mock<ControllerBase>(MockBehavior.Loose);
var routeDataMock = new Mock<RouteData>();
var wantedRouteValues = new Dictionary<string, string>();
wantedRouteValues.Add("key1", "value1");
var routeValues = new RouteValueDictionary(wantedRouteValues);
routeDataMock.SetupGet(r => r.Values).Returns(routeValues); <=== Fails here
var controllerContext = new ControllerContext(httpContextMock.Object, routeDataMock.Object, controllerMock.Object);
Run Code Online (Sandbox Code Playgroud)
单元测试失败:System.ArgumentException:不可覆盖的成员上的设置无效:r => r.Values
由于构造函数是RouteData(RouteBase,IRouteHandler),因此创建伪RouteData也不起作用.
这里重要的类是抽象类RouteBase,它有GetRouteData(HttpContextBase)方法,它返回一个RouteData实例,我试图伪造的类.把我带到圈子里!
对此的任何帮助都是最受欢迎的.
我只是想模拟ActionExecutedContext,传递它,让过滤器稍微工作并检查结果.
有帮助吗?
你可以在这里找到过滤器的来源
(它有点改变,但目前不是重点).
所以 - 我想要单元测试,RememberUrl过滤器足够智能,可以在会话中保存当前的URL.
更新:
基于我收到的几个答案,我只想说明我很清楚如何使用模拟框架来模拟HttpContext.我更感兴趣的是,与使用HttpContext周围的包装类相比,模拟HttpContext的优点和缺点是什么.
我正在寻找在ASP.Net MVC中构建可测试控制器时如何处理HttpContext的意见.在阅读之后,似乎有两种思想流派 - 或者构建HttpContextBase并使用模拟框架为您的单元测试生成所需的存根/模拟,或者在您打算使用的HttpContext区域周围构建不可知的包装类.
现在我倾向于建立HttpContextBase.看起来它既是更快的开发过程又更容易维护,因为您不必花时间开发和维护其他包装类.我可以看到包装类如何有益,因为它们抽象出底层实现并将控制器的上下文与请求分开 - 但我不确定这是否值得设置和维护的额外开销.
您认为这两种方法之间的利弊是什么?您何时会选择另一种方法?某些类型的开发是否比其他开发更适合其中一种解决方案?
因为这似乎是一个常见的问题,大多数单元测试和使用ASP.Net MVC的团队必须处理,你或者你将如何处理这个问题?如果您已经解决了这个问题,那么您的解决方案是如何运作的,现在您会采取哪
自从我从MVC 2升级到MVC 3 RC后,使用TryUpdateModel会导致NullReferenceException.仅当将我的操作方法作为单元测试的一部分运行时,才会出现此问题.在实际服务器上运行它按预期工作.
这是异常的堆栈跟踪:
System.NullReferenceException:未将对象引用设置为对象的实例.在System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext)的System.Web.Mvc.ValueProviderFactoryCollection.<> c_ DisplayClassc.b _7(ValueProviderFactory factory)处于System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()处于System.1..ctor(IEnumerableSystem.Web.Mvc.Controller.TryUpdateModel中System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext)的System.Linq.Enumerable.ToList [TSource](IEnumerable`1 source)上的Collections.Generic.List 1 collection)[ TModel](TModel模型,字符串前缀)
......我自己的代码来自这里......
如果重要,我的控制器有以下签名:
[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult Edit(int id, FormCollection collection)
{
}
Run Code Online (Sandbox Code Playgroud)
我的猜测是,这与DI在MVC3中工作的新方式有关,但我无法弄清楚我做错了什么.也许在MVC 3中需要一些DI设置,但在MVC 2中不需要?
asp.net-mvc dependency-injection model-binding asp.net-mvc-3
我有一个FakeHttpContext我一直在尝试修改以包含一些标题用于测试目的
public static HttpContext FakeHttpContext()
{
var httpRequest = new HttpRequest("", "http://stackoverflow/", "");
var stringWriter = new StringWriter();
var httpResponse = new HttpResponse(stringWriter);
var httpContext = new HttpContext(httpRequest, httpResponse);
var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
new HttpStaticObjectsCollection(), 10, true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc, false);
httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null, CallingConventions.Standard,
new[] { typeof(HttpSessionStateContainer) },
null)
.Invoke(new object[] { sessionContainer });
return httpContext;
}
Run Code Online (Sandbox Code Playgroud)
此作品,未经头,但是当我添加任何的代码行中之间的HttpRequest和StringWriter的线.
httpRequest.Headers.Add("blah", "1234");
httpRequest.Headers["blah"] = "1234";
Run Code Online (Sandbox Code Playgroud)
它抛出
System.Web.dll中发生了'System.PlatformNotSupportedException'类型的异常,但未在用户代码中处理
我们需要渲染一个ActionResulta string来向我们的内部搜索引擎索引添加页面.我们决定将此解决方案渲染为字符串.
我遇到了ExecuteResult用于处理View 的调用的问题.
var oldController = controllerContext.RouteData.Values["controller"];
controllerContext.RouteData.Values["controller"] =
typeof(TController).Name.Replace("Controller", "");
viewResult.ExecuteResult(controllerContext); // this line breaks
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
"Object reference not set to instance of object" error.
我已经确认viewResult不是null,所以必须在内部抛出异常ExecuteResult.
我们还能错过什么?
我想测试我的MVC应用程序,并且想模拟HttpContext。我正在使用Moq框架,这是我模拟HttpContext所做的工作:
[SetUp]
public void Setup()
{
MyUser myUser = new MyUser();
myUser.Id = 1;
myUser.Name = "AutomatedUITestUser";
var fakeHttpSessionState =
new FakeHttpSessionState(new SessionStateItemCollection());
fakeHttpSessionState.Add("__CurrentUser__", myUser);
ControllerContext mockControllerContext = Mock.Of<ControllerContext>(ctx =>
ctx.HttpContext.User.Identity.Name == myUser.Name &&
ctx.HttpContext.User.Identity.IsAuthenticated == true &&
ctx.HttpContext.Session == fakeHttpSessionState &&
ctx.HttpContext.Request.AcceptTypes ==
new string[]{ "MyFormsAuthentication" } &&
ctx.HttpContext.Request.IsAuthenticated == true &&
ctx.HttpContext.Request.Url == new Uri("http://moqthis.com") &&
ctx.HttpContext.Response.ContentType == "application/xml");
_controller = new SomeController();
_controller.ControllerContext = mockControllerContext; //this line is not working
//when I see _controller.ControllerContext in …Run Code Online (Sandbox Code Playgroud) asp.net-mvc ×6
c# ×4
httpcontext ×2
mocking ×2
moq ×2
unit-testing ×2
.net ×1
tdd ×1
testing ×1