Skip to content
ladenedge edited this page Nov 12, 2012 · 3 revisions

This library contains a full rewrite of the standard multipart stream providers:

In normal usage, they work just like the Microsoft counterparts. The difference between the two is only evident in unit tests. Whereas the Microsoft classes require multipart file attachments to be written to the filesystem, the Testable variety offer a mockable interface based on the SystemWrapper library.

Controller Design

My suggestion for the design of a unit-testable Web API controller is to inject the provider via the controller constructor:

public MyController(TestableMultipartFormDataStreamProvider multipartProvider)
{
   this.multipartProvider = multipartProvider;
}

From there you can construct a concrete TestableMultipartFormDataStreamProvider in an IDependencyResolver.

Because the Testable classes derive from MultipartStreamProvider, usage of the provider will be exactly the same in your actions.

Unit Testing

Unit testing controllers that depend on the Testable classes is now possible without touching the filesystem. Simply inject an IFile mock into the provider at test-time, and (if appropriate) return a mocked stream. Here's an example with Moq:

[Test]
public void ControllerTest()
{
   var path = Fixtures.CreateAnonymous<string>();
   var bufferSize = Fixtures.CreateAnonymous<int>();
   var fileMock = new Mock<IFile>();
   var provider = new TestableMultipartFormDataStreamProvider(path, bufferSize, fileMock.Object);

   var ctrl = new MyController(provider);

   // exercise controller
}

The code in the library that uses IFile are these couple of lines in TestableMultipartFileStreamProvider.GetStream, the method that provides a Stream instance for the content writer:

 var stream_wrapper = FileWrapper.Create(fullpath, BufferSize, FileOptions.Asynchronous);
 return stream_wrapper.StreamInstance;

This code (when not mocked) is wrapping File.Create, and uses IFileStream, also found in the SystemWrapper library.

Clone this wiki locally