sanjeev40084
sanjeev40084

Reputation: 9617

Unit test and Session?

I have a routine something like this:

public bool IsValidEmployee(string email, string password)
{
  bool valid = false;
  var employee = dataAccess.GetEmployee(email, password);

  if(employee! = null)
   {
      valid = true;
      HttpContext.Current.Session["Employee"] = employee;
   }

   return valid;
}

My unit test:

[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("C:\Projects", "/")]
[UrlToTest("http://localhost:59349/")]
public void GetEmployeeTest()
{
   Domain target = new Domain();        

   var mockHttpContext = new Mock<HttpContextBase>();
   mockHttpContext.SetupSet(c => c.Session["Employee"] = It.IsAny<object>());

   Assert.IsTrue(target.IsValidEmployee("[email protected]", "test");                
 }

The code fails as

Object Null Reference on 'HttpContext.Current.Session["Employee"] = employee;'

Any suggestions how i can fix this error?

Upvotes: 2

Views: 4749

Answers (4)

S.Robins
S.Robins

Reputation: 703

Which code fails? Is this a test failure due to an error in your method, or is the occurring error in the test code itself?

Regardless of how you might improve your test (and this may come across as sounding a bit obvious), but I wonder if you have set a break-point on the setup line in your test method, and actually checked that the object you are trying to assign a value to is null? If this is the case, you need to check your setup, and as others may have said you'll probably need to mock your session in such a way as to ensure the setup portion of your test won't fail.

Cheers.

Upvotes: 0

StingyJack
StingyJack

Reputation: 19469

Moles will allow you to intercept and substitute the calls to session.

http://research.microsoft.com/en-us/projects/pex/getstarted.pdf

Using session should be avoided if at all possible due to the burden it places on the server.

That code looks pretty error prone, but maybe that's why you are adding unit tests.

Upvotes: 1

np-hard
np-hard

Reputation: 5815

I think you also need to mock getter for the session...

public void GetEmployeeTest()
    {
        Domain target = new Domain();
        var mockHttpContext = new Mock<HttpContextBase>();
        var mockSession = new Mock<HttpSessionStateBase>();
        mockHttpContext.SetupGet(c => c.Session).Returns(mockSession.Object);
        mockHttpContext.SetupSet(c => c.Session["Employee"] = It.IsAny<object>());
        Assert.IsTrue(target.IsValidEmployee("[email protected]", "test"));
    }

Upvotes: 0

John Sobolewski
John Sobolewski

Reputation: 4572

I don't believe just mocking out HttpSession is enough to get the session in your method to take the mocked behavior. You need a way to inject that dependency.

You could redesign your function to take in the session object as a param. This would make your method testable

For example

public bool IsValidEmployee(string email, string password, HttpSessionStateBase session)
{
  bool valid = false;
  var employee = dataAccess.GetEmployee(email, password);

  if(employee! = null)
   {
      valid = true;
      session["Employee"] = employee;
   }

   return valid;
}

Additionally you could create a "SessionManager" that could impliment ISessionManager that would wrap all your access to session state and pass that around making it even more testable thus decoupling the responsibility of how and where to persist session state from Validating an Employee.

Upvotes: 2

Related Questions