Method I am unit testing checks for a session variable like
if(Session["somevar"] != null)
{
// rest of the code
}
In my test, not able to get rid of this since Session
is null, it's throwing null referrence exception.
To bypass this, I have tried mocking it like below but no luck
System.Web.Moles.MHttpContext.AllInstances.SessionGet = (HttpContext cntx) =>
{ return (HttpSessionState)cntx.Session["somevar"]; }
I even tried method mention here to simulate HttpContext and then doing below
HttpContext.Current = new HttpContext(workerRequest);
HttpContext.Current.Session["somevar"] = value;
But again no luck. This time, though the HttpContext.Current
is not null but HttpContext.Current.Session
and hence throws null ref exception.
Any idea how can I mock this/by pass this in my test [Without using any external DLL or main code change. Sorry, but can't afford to do so].
Thanks and appreaciate lot your help.
Update 2013:
The bad news now is that the Moles framework was a Microsoft Research (MSR) project, and will not be supported in Visual Studio 2012. The great news is that Microsoft has now integrated the MSR project into the mainline framework as Microsoft Fakes.
I found an article that solves the problem you had, using the Fakes framework instead of the Moles framework:
http://blog.christopheargento.net/2013/02/02/testing-untestable-code-thanks-to-ms-fakes/
Here's an updated version of my previous answer that uses the Fakes framework instead of Moles.
You might even be able to make it look more like the Moles version I posted before, though I haven't tried that out yet. I'm just adapting the article's code to my answer :)
Before 2013 edit:
You said you want to avoid changing the code under test. While I think it should be changed, as directly accessing session state like that is a bad idea, I can understand where you're coming from (I was in test once...).
I found this thread describing how someone moled both
HttpContext
andHttpSessionState
to get around this problem.Their code ended up looking like this:
I'd go even farther and implement
ItemGetString
with a dictionary:Before edit:
I usually solve problems like this by encapsulating global state with an abstract class or interface that can be instanced and mocked out. Then instead of directly accessing the global state, I inject an instance of my abstract class or interface into the code that uses it.
This lets me mock out the global behavior, and makes it so my tests don't depend on or exercise that unrelated behavior.
Here's one way to do that (I'd play with the factoring a bit tho):
This would require changes to your code-under-test, but it is the type of change that is good both for testability and for portability of the code.