Simulating HttpContext with Sessions and POSTs for ASP.NET
Here’s a little something I’ve been hacking together at work, so that we can do some unit testing on my current project. It’s largely based on this post by Phil Haack, but adds support for using Sessions (by assigning to the Session property) and doing Http POSTs as well as GETs, both of which are necessary for our tests, and were requested in the comments on Phil’s post.
As you can see, the Session support is bare-bones at the moment, because what’s there satisfies my needs for now. If you wander outside just stashing stuff in the session, you’ll get a handy exception to tell you that you’ve surpassed what the code can currently do.
Hope it helps you!
namespace ElectronicFieldBook.Tests { /// <summary> /// Allows us to set the HTTP context with a valid simulated request /// From <http://haacked.com/archive/2005/06/11/Simulating_HttpContext.aspx> /// </summary> public static class WebRequestSimulator { public class WithoutSession { public static HttpContext Get() { return Get(“localhost”, “”, string.Empty); } public static HttpContext Get(string host, string page, string query) { SimulatedHttpRequest req = new SimulatedHttpRequest(“GET”, host, page, query); return HttpContext.Current = new HttpContext(req); } public static HttpContext Post(string host, string page, string query, string body) { SimulatedHttpRequest req = new SimulatedHttpRequest(“POST”, host, page, query); req.Body = body; return HttpContext.Current = new HttpContext(req); } } public static HttpContext Get() { return AddSessionState(WithoutSession.Get()); } public static HttpContext Get(string host, string page, string query) { return AddSessionState(WithoutSession.Get(host, page, query)); } public static HttpContext Post(string host, string page, string query, string body) { return AddSessionState(WithoutSession.Post(host, page, query, body)); } public static HttpContext AddSessionState(HttpContext context) { IHttpSessionState ssn = Session; if (ssn != null) { SessionStateUtility.AddHttpSessionStateToContext(context, ssn); } return context; } private static IHttpSessionState session; public static IHttpSessionState Session { get { return session; } set { session = value; } } /// <summary> /// Used to simulate an HttpRequest. /// </summary> public class SimulatedHttpRequest : SimpleWorkerRequest { private string verb; private string host; private string body = string.Empty; public string Body { get { return body; } set { body = value; } } public SimulatedHttpRequest( string verb, string host, string page, string query) : this(“/”, AppDomain.CurrentDomain.BaseDirectory, verb, host, page, query, null) { } public SimulatedHttpRequest( string appVirtualDir, string appPhysicalDir, string verb, string host, string page, string query, TextWriter output) : base(appVirtualDir, appPhysicalDir, page, query, output) { if (string.IsNullOrEmpty(verb)) throw new ArgumentNullException(“verb”, “Verb cannot be null nor empty.”); if (string.IsNullOrEmpty(host)) throw new ArgumentNullException(“host”, “Host cannot be null nor empty.”); this.verb = verb; this.host = host; } /// <summary> /// Gets the name of the server. /// </summary> /// <returns></returns> public override string GetServerName() { return host; } /// <summary> /// Maps the path to a filesystem path. /// </summary> /// <param name=”virtualPath”>Virtual path.</param> /// <returns></returns> public override string MapPath(string virtualPath) { return Path.Combine(this.GetAppPath(), virtualPath); } public override string GetHttpVerbName() { return verb; } public override byte[] GetPreloadedEntityBody() { return new UTF8Encoding().GetBytes(Body); } public override int GetPreloadedEntityBodyLength() { return GetPreloadedEntityBody().Length; } public override string GetKnownRequestHeader(int index) { bool isPost = verb == “POST”; if (!isPost) return base.GetKnownRequestHeader(index); if (index == HeaderContentType) { return “application/x-www-form-urlencoded; charset=utf-8″; } else if (index == HeaderContentLength) { return GetPreloadedEntityBodyLength().ToString(); } return base.GetKnownRequestHeader(index); } } public class SimulatedHttpSessionState : IHttpSessionState { private IDictionary objects = new Dictionary<object, object>(); private bool isAbandoned = false; public bool IsAbandoned { get { return isAbandoned; } set { isAbandoned = value; } } public void Add(string name, object value) { objects.Remove(name); objects.Add(name, value); } public void Clear() { objects.Clear(); } public int Count { get { return objects.Count; } } public System.Collections.IEnumerator GetEnumerator() { return objects.Values.GetEnumerator(); } public void Remove(string name) { objects.Remove(name); } public void RemoveAll() { Clear(); } public void RemoveAt(int index) { throw new Exception(“The method or operation is not implemented.”); } public object this[int index] { get { throw new Exception(“The method or operation is not implemented.”); } set { throw new Exception(“The method or operation is not implemented.”); } } public object this[string name] { get { return objects[name]; } set { Add(name, value); } } public void Abandon() { isAbandoned = true; } public int CodePage { get { throw new Exception(“The method or operation is not implemented.”); } set { throw new Exception(“The method or operation is not implemented.”); } } public HttpCookieMode CookieMode { get { throw new Exception(“The method or operation is not implemented.”); } } public void CopyTo(Array array, int index) { throw new Exception(“The method or operation is not implemented.”); } public bool IsCookieless { get { throw new Exception(“The method or operation is not implemented.”); } } public bool IsNewSession { get { throw new Exception(“The method or operation is not implemented.”); } } public bool IsReadOnly { get { throw new Exception(“The method or operation is not implemented.”); } } public bool IsSynchronized { get { throw new Exception(“The method or operation is not implemented.”); } } public System.Collections.Specialized.NameObjectCollectionBase.KeysCollection Keys { get { throw new Exception(“The method or operation is not implemented.”); } } public int LCID { get { throw new Exception(“The method or operation is not implemented.”); } set { throw new Exception(“The method or operation is not implemented.”); } } public SessionStateMode Mode { get { throw new Exception(“The method or operation is not implemented.”); } } public string SessionID { get { throw new Exception(“The method or operation is not implemented.”); } } public HttpStaticObjectsCollection StaticObjects { get { throw new Exception(“The method or operation is not implemented.”); } } public object SyncRoot { get { throw new Exception(“The method or operation is not implemented.”); } } public int Timeout { get { throw new Exception(“The method or operation is not implemented.”); } set { throw new Exception(“The method or operation is not implemented.”); } } } } }
2 Comments »>