Mocking multipart/form-data HttpRequestMessage for testing ASP.NET ApiController


I recently had a problem where I needed to unit test an ApiController action that read data off of the controller’s request object, in other words, something that looks like this:

The real-world action receives a multipart/form-data request (a form), which contains an uploaded file as one of its fields. Reading the form fields and file data from the ‘Request’ object is not particularly difficult, but figuring out how to mock the HttpRequestMessage was a non-trivial exercise, which is why I thought I’d share it here.

Note: there is a distinct difference between how this gets done for ASP.NET Web API and how it can be done for MVC (which is better supported on StackOverflow, etc from what I could find)

The final solution is actually reasonably straightforward, but it took me a long time to figure out, so here goes

Another note: the unit testing framework used is NUnit and the assumption here is that you already have your test environment set up, with a class to contain the tests for your ApiController

First, I created a helper method in my test class to build the mocked MultiPartFormDataContent

Note: The ‘boundary’ can be anything you choose as long as it doesn’t appear in the form data (see W3.org for more info on multipart/form-data)

Now that you have the MultiPartFormDataContent mock set up, the controller under test can then be created like this (for example):

And voila! Controller action relying on ‘Request’ data can now be tested.

Advertisements

9 Replies to “Mocking multipart/form-data HttpRequestMessage for testing ASP.NET ApiController”

  1. This is a great write-up and was really helpful to get me started so thank you for that. However, I’m wondering if you do anything with clean-up to avoid test.file from being written into the file system every time a test runs. I have multiple tests that will run asynchronously so I’m generating the file name for each test by using Guid.NewGuid(), which means each test then creates a new file in the file system. I’ve got a cleanup method with a TestFixtureTearDown, but I’m getting an error when trying to delete the files because the files are being used by other processes.

    Thanks!

    1. Hi Andrew,

      I’ve been meaning to write to you, but keep forgetting! I no longer have access to the project where I used this mock, but as far as I can recall, we didn’t really concern ourselves about the file cleanup (for better or for worse). Have you solved the problem? If so, I would love to incorporate your solution into this post.

      Cheers!

  2. Hi William,

    Nice writeup, it helped me in unit testing the controller.
    To avoid test file creation and cleanup we changed:
    From:
    using (var outFile = new StreamWriter(testFile))
    {
    outFile.WriteLine(“bleh bleh bleh”);
    }

    var fileStream = new FileStream(testFile, FileMode.Open, FileAccess.Read);
    To:
    var streamContent = new StreamContent(new MemoryStream(new byte[0]));

    It does the job!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s