Mocking Session in ASP.NET with Moq and VB.NET

logo

It has been a few years since I have had the chance to explore the latest enhancements to ASP.NET. The development in my day job was locked into traditional ASP.NET forms just before MVC 1.0 was released and there has not been any opportunity to change. TDD, dependency injection and inversion of control containers all slipped by with me staring at them with my nose pressed against the window. I also develop in php with CodeIgniter, so I am quite familiar with the idea of MVC and was thoroughly excited when recently, the company I work for, began brewing the idea for a new project. Now was the time to change, so I stocked up on books and blog articles and began the big catch up. I won’t go on about how great MVC is, especially when I spent many hours battling against the web form paradigm – its such an anti-web way of doing things but with these new ways of working, I now feel a new vigour for .Net web development.

My journey found me working with Moq and although it is pretty self explanatory, most examples and articles are in C# and the documentation for the library is a little sparse. I don’t find the switching between C# and VB.NET very difficult as there is mostly only a syntax difference between them but I did find a problem when, in my unit tests, I needed to assert that entries in the session had been set correctly. So here is how to do it in VB.NET.

Checking a value has been set in Session

The first thing that you need is a session object that you can look at in your tests. It needs to inherit from HttpSessionStateBase and is pretty simple as the session is just a key-value store – we can use a generic dictionary to store the values we want to check:

Public Class HttpSessionMock
    Inherits HttpSessionStateBase
    Private ReadOnly objects As New Dictionary(Of String, Object)()
 
    Default Public Overloads Overrides Property Item(ByVal name As String) As Object
        Get
            Return If((objects.ContainsKey(name)), objects(name), Nothing)
        End Get
        Set(ByVal value As Object)
            objects(name) = value
        End Set
    End Property
 
    Public Overrides Sub Add(ByVal name As String, ByVal value As Object)
        objects.Add(name, value)
    End Sub
End Class

So we now have a session store and we can then use Moq to utilise that in our controller during our test. This is done be setting up a controller context:

 'Create a real mock session object to check value against
 Dim session As New HttpSessionMock()
 
 'Create a moq controller context
 Dim mockcontext As New Mock(Of ControllerContext)
 
 'Ensure our session object is returned when the session is requested
 mockcontext.SetupGet(Function(c As ControllerContext) c.HttpContext.Session).Returns(session)
 
 'set our controller context to be the moq context
 MyController.ControllerContext = mockcontext.Object

We can then run our controller action that sets a value in our mock session object and assert that the correct value is set as follows:

  'run the controller action
 Dim result = MyController.SomeAction()
 
 'assert the session contains the object we expect
 Assert.IsInstanceOfType(session.Item("SessionItemToCheck"), GetType(ExpectedSessionObject))
 
 'TODO:other tests to ensure session item is correct

Ensuring a value is returned from Session

You can use the above real mock session object to do this in exactly the same way but we can also setup Moq to return a particular value from session directly:

'create a test object/value we want session to return
Dim MySessionValue as New SomeObject()
 
'create our moq controller context
Dim mockcontext As New Mock(Of ControllerContext)
 
'ensure our test object gets returned by the moq session
mockcontext.SetupGet(Function(c As ControllerContext) c.HttpContext.Session("SessionItemToTest")).Returns(MySessionValue)
 
'assign our context to the controller	
controller.ControllerContext = mockcontext.Object
 
'TODO: run controller action and assert results

When I look at the code now, I realise that it is quite simple to achieve. However, it took me a little while to get my head around Moq and figure this out as all the examples out there seemed to be trying to do so much more than solely testing session state. It confused me anyhow.

 

Leave a Reply

Your email address will not be published. Required fields are marked *