Reputation: 75
public async Task <ActionResult>Select(DWorkingTimeSelection dto) {
var session = HttpUtils.GetSeesion<User>("USER");
}
public static T GetSeesion<T>(string key) where T : class
{
if (HttpContext.Current == null)
{
return default(T);
}
return HttpContext.Current.Session[key] as T;
}
public async Task <ActionResult>Select(DWorkingTimeSelection dto) {
var session = HttpUtils.GetSeesion<User>("USER");
}
public static T GetSeesion<T>(string key) where T : class
{
if (HttpContext.Current == null)
{
return default(T);
}
return HttpContext.Current.Session[key] as T;
}
I use nunti to mock a request. And I add the SessionStateItemCollection to the Controller 's ControllerContext . I found that the HttpContext.Current is null but the Controller 's Session[] is not null because it get from the Controller 's ControllerContext . So what should I do to avoid the HttpContext.Current is null while mocking a request
Upvotes: 1
Views: 1391
Reputation: 8781
You can mock the HttpContext:
public static HttpContext FakeHttpContext(HttpRequest request)
{
var stringWriter = new StringWriter();
var httpResponse = new HttpResponse(stringWriter);
var httpContext = new HttpContext(request, 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;
}
[TestMethod]
public void ActionTest()
{
var request = new HttpRequest(string.Empty, "url to the action that you are testing", string.Empty)
{
RequestType = "GET"
};
HttpContext.Current = FakeHttpContext(request);
var controller = new YourController();
//You need the get a Result property since it is an async action
var result = controller.ActionToTest(//the parameters that your action expects).Result;
Assert.IsNotNull(result);
}
EDIT (answering the questions in your comment):
In order to get a session you need to call HttpContext.Current.Session
and not the HttpContext.Current.Session["id"]
because HttpContext.Current.Session["id"]
tries to get an id
key from your session.
Once you store it there it will be available through this call. You can test it:
HttpContext.Current.Session["id"] = 5;
Assert.AreEqual(HttpContext.Current.Session["id"],5);
Regarding the httpContext.Items
statement:
(From MSDN)HttpContext.Items
is a key/value collection that can be used to organize and share data between an IHttpModule
interface and an IHttpHandler
interface during an HTTP request.
For the statement that you are asking for, simply create a new HttpSessionState
object by using reflection (because it has only internal constructors) associates it with the HttpSessionStateContainer
that you created earlier, and store it in HttpContext.Items
under AspSession
. And an interesting thing is that HttpContext.Current.Session
actually is a shortcut to HttpContext.Items["AspSession"]
. So the assignment of HttpSessionState object to the AspSession
key is the one that makes HttpContext.Current.Session
work.
Upvotes: 2
Reputation: 75
Well,after mocking the HttpContext as Alex Art said .
Calling the following method will be fine.
var sessionItems = new SessionStateItemCollection();
sessionItems["SessionKey"] = new MyCustomObject();
SessionStateUtility.AddHttpSessionStateToContext(fakeHttpContext,
new HttpSessionStateContainer(SessionNameStorage.Suser,
sessionItems,
new HttpStaticObjectsCollection(),
20000,
true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc,
false
));
Upvotes: 2