MVC6 Integration Testing With AntiForgery

The source code for this post can be found on my GitHub repository.  It was developed using only RC1-final packages.  I will update the code once RC2-final becomes available.

As you all know by now ASP.Net core (ASP.Net 5) and MVC6 is now in RC1.  With this release there are PLENTY of changes when compared to the previous version of ASP.Net.  One of the many changes in MVC6 when compared to MVC5 is that you can now do native integration testing.  This article solely focuses on integration testing of MVC controllers that utilize the ValidateAntiForgery attribute.

In the sample source code you’ll see the SampleMVC project which is based on the ASP.NET5 template with individual accounts.  In the SampleMVC project you’ll notice the Account Controller.  Within this controller you’ll see a Register method that takes a parameter of RegisterViewModel; this method also has an attribute of ValidateAntiForgeryToken.  This is the method that we want to test, and the security measures implemented as part of this attribute are significant.

ValidateAntiForgeryToken

To get start on the testing part of things you’ll notice the SampleMVCTest project.  This project is based on “xUnit Test Project (DNX)” template available on SideWaffle.

At this point I want to highlight a couple of extension methods.  The first HttpClient.PostFormDataAsync; this method is necessary because MVC controllers expect URL encoded form data.

The remaining extension methods are geared towards getting both (cookie and form) AntiForgeryTokens from an HttpResponse object.  These methods are HttpResponse.GetAntiForgeryFormToken and HttpResponse.GetAntiForgeryCookie.

In order to run the MVC site within the context of the test we’ll need to initialize a Test Server.  For more information on the Test Server and what it does, a good reference is the asp.net docs (http://docs.asp.net/en/latest/testing/integration-testing.html).

In the base integration test you’ll find a InitTestServer method.  This method will spin up a test server and setup the pipeline for MVC integration testing

InitTestServer

One thing I want to point out in InitTestServer is the ConfigureAntiForgery  method which allows you to hard-code values for the AntiForgery form token and cookie names.  Without this line of code, the names for the form and cookie tokens are randomly generated.
Important: The ConfigureAntiForgery method should not be used outside of testing code.

Putting it all together:

TheTest

This is what your actual test will look like.  Again, we’re testing the Register method on the account controller.  Within our test we will first execute the HttpGet method; the response to this request will provide us with both the form and cookie AntiForgery tokens.

Once we have both token values we will then use them to submit an HttpPost request.   You’ll see how these values are used in the code above.

Enjoy!  Feel free to ask questions and comment.

-Isaac Martinez

Leave a comment