Monthly Archives: July 2017

Testing ASP.NET with Sessions and HttpContext

In my last post I advocated strongly for writing tests for any project that you inherit that does not have them.

As I begin to build a test suite for the code I am now responsible for, I am going to be writing about challenges I run into writing tests in a framework with which I am not heavily experienced.

Mocks Are Your Friend

When writing tests, it is important to isolate the code that you are testing to make sure that only it is being tested. You usually want to test specific behavior from a specific scenario.

One of the ways you can do this is by mocking or faking the responses from any other parts of the code that it calls.

The framework that I have decided to use for this is called Moq and makes it pretty easy to create a small stand in object that fakes the response you want.

Using these I was able to isolate problem areas in the test to determine the resources I needed to get the code to operate correctly.

HttpContext in Your Test

The project I am working on is an ASP.NET application. The way it was designed relies on redirects, the HttpContext.Current, and Sessions. This means that testing things can get tricky.

I was trying to Mock out the responses I needed for my test and made good headway doing so. But after doing a bunch of research along with trial and error, the best place I found to create the HttpContext for the test is in the TestInitialize portion of the test.


        [TestInitialize]
        public void TestInit()
           {
            var request = new HttpRequest("", "http://localhost", "");
            var response = new HttpResponse(new StringWriter());
            var testHttpContext = new HttpContext(request, response);
            HttpContext.Current = testHttpContext;
           }

Their are many cases where you would just want to make a simple Mock of the HttpContext and whatever you were trying to get out of it in the function, but the function I was testing used so many aspects of it that it just made sense to create one in the test initialization.

Session in Your Test

The main problem I ran into was with Session. Every use of Session in the code I was testing gave an error of “Object reference set to Null.” Additionally their did not seem to be a good way to Mock it out. It is not created by default in a new HttpContext, so putting that in the TestInitialize section did not work.

After doing a lot of digging, I finally found a way to add a new Session to the HttpContext. You have to create a HttpSessionStateContainer and then use the SessionStateUtility to add it to your HttpContext object in the TestInitialize code.


var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
                                            new HttpStaticObjectsCollection(), 10, true,
                                            HttpCookieMode.AutoDetect,
                                            SessionStateMode.InProc, false);
SessionStateUtility.AddHttpSessionStateToContext(testHttpContext, sessionContainer);

If you are tearing your hair out trying to figure out how searching for things like “C# asp.net test set httpcontext” or “C# asp.net test mock session”, then hopefully this helps you.

Happy Testing

Inheriting a Large Project with No Tests

Recently I have begun working part time for a small startup that has had a base version of their software already created by a company that used an overseas team. The codebase is large and in a language and framework that I have not worked in recently and uses features that I had not previously heard of.

On top of that their are large blocks of commented code, hardcoded values for things that need to be in a config file, and not one test.

As a professional software developer, when you are creating a large project for the company you work for, for a client or even for yourself, you absolutely should write test. Many people would even say you should write the tests first (TDD).

So what do you do when you inherit a large, legacy project that has zero tests?

Step One: Get a Build Working

Code is really difficult to test if the code doesn’t work or you don’t know how it should work. First you need to make sure you have a build that runs. If it doesn’t run, time to debug and get it running. It helps if you have someone who knows how it should be working so that even if it does not work properly, you can make it.

Step Two: Begin to Eat the Elephant

How do you eat an Elephant? One bite at a time.

Pick a small piece of the code and write a test for it. For the first test, try for a simple piece of code that does not rely on a bunch of things being mocked out (learned this the hard way).

Step Three: Take Another Bite

Repeat step 2 until you have reasonably good test coverage of the project. This does not necessarily mean 100% test coverage.

Bonus

If the code is particularly troublesome to get working, it is actually a good idea to write tests for sections of the code that do not work properly as you go through step 1. When something does not work, write a test that will pass when it does work and then fix the code.

Most importantly, remember to be a professional and write tests.