NopCmmerce的FakeHttpContext类
在 Web 中进行测试驱动的开发,比较大的困难是模拟 HttpContext;
1.Nop提供了完整的FakeHttpContext实现,如图
1.FakeHttpContext的作用。
控制器进行单元测试时模拟web上下文环境,还有一些其他对HttpContext有依赖的组件也可以使用Fake从而进行组件的单元测试。
2.例举Nop中使用到FakeHttpContext的地方
(1).NopEngine(初始化NopEngine时,是web环境就注册真实HttpContext,否则注册FakeHttpContext)
//HTTP context and other related stuff builder.Register(c => //register FakeHttpContext when HttpContext is not available HttpContext.Current != null ? (new HttpContextWrapper(HttpContext.Current) as HttpContextBase) : (new FakeHttpContext("~/") as HttpContextBase)) .As<HttpContextBase>() .InstancePerHttpRequest(); builder.Register(c => c.Resolve<HttpContextBase>().Request) .As<HttpRequestBase>() .InstancePerHttpRequest(); builder.Register(c => c.Resolve<HttpContextBase>().Response) .As<HttpResponseBase>() .InstancePerHttpRequest(); builder.Register(c => c.Resolve<HttpContextBase>().Server) .As<HttpServerUtilityBase>() .InstancePerHttpRequest(); builder.Register(c => c.Resolve<HttpContextBase>().Session) .As<HttpSessionStateBase>() .InstancePerHttpRequest();
(2)RoutesTests( Route依赖HttpContextBase,可以用Fake类代替 )
[Test] public void Blog_routes() { //TODO why does it pass null instead of "new BlogPagingFilteringModel()" as it's done in real application? The same is about issue is in the other route test methods "~/blog/".ShouldMapTo<BlogController>(c => c.List(null)); "~/blog/rss/1".ShouldMapTo<BlogController>(c => c.ListRss(1)); "~/blog/2/".ShouldMapTo<BlogController>(c => c.BlogPost(2)); "~/blog/2/test-se-name".ShouldMapTo<BlogController>(c => c.BlogPost(2)); //TODO validate properties such as 'Tag' or 'Month' in the passed BlogPagingFilteringModel. The same is about issue is in the other route test methods //"~/blog/tag/sometag".ShouldMapTo<BlogController>(c => c.List(new BlogPagingFilteringModel() { Tag = "sometag" })); //"~/blog/month/3".ShouldMapTo<BlogController>(c => c.List(new BlogPagingFilteringModel() { Month = "4" })); }
(3)其他组件,如WebHelperTests,AdminAuthorizeAttributeTests都依赖了HttpContextBase
总结:这些Fake类为单元测试提供了模拟的Web上下文环境。,再也不用担心控制器以及类库因为用了HttpContextBase(最常见的包括Session,Request,Response)而变得难以进行单元测试了(但在控制器中还是应该尽量少用这些)