TypeMock - Testing the ASP.NET FileUpload control SaveAs method

Actually the blog title is somewhat misleading; the objective was to create a method that we can pass a FileUpload control into and it will save it to a temporary file (guid filename) and return the name so that we can process it further.

Unfortunately this objective became quite complicated once we threw TDD into the mix.   We had to throw out what could have been an easy fileUpload.SaveAs(tempFile) command and substitute it with a process that we can Unit Test.  TypeMock helps us do this quite nicely
Cool  Below is the process we will be using from ASP.NET and our Unit Test:

    /// <summary>
    /// Save the FileUpload data as a temp file
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="fileUpload"></param>
    /// <returns></returns>
    public string SaveFileUploadAsTempFile(FileUpload fileUpload)
    {
        // Generate a Temp file in the App_Data\Temp folder
        // and return the file name
        string tempFile = GetTempFile();
 
        // Store the FileUpload control's InputStream (the file)
        // to a fileData stream.  We do it this way for Unit Testing
        // purposes
        Stream fileData = fileUpload.PostedFile.InputStream;
 
        // Use the Stream's StrToFile extension to save the contents
        // to our temp file
        fileData.StrToFile(tempFile);
 
        // Return the name of the temp file that holds our
        // file contents
        return tempFile;
    }

Note: In this BLOG I discuss the FileToStr() and StrToFile() extensions; the StreamExtensions.cs file has comparable code (see end for full source location).

I commented the unit test heavily so I'll just post the Unit Test in its entirety for your review: 

using System;
using System.IO;
using System.Web;
using System.Web.UI.WebControls;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
using TypeMock;
using HttpUtility.Tests.Base;
using HttpUtility.Storage;
 
// Holds our string and stream extensions for StrToFile()
using Library.Utility.Extensions;
 
namespace HttpUtility.Tests
{
    /// <summary>
    /// Summary description for FileUploadFixture
    /// </summary>
    [TestClass]
    public class FileUploadFixture : TestBase
    {
        public FileUploadFixture() {}
 
        [TestMethod]
        public void FileUpload_ControlCanWriteToAppData()
        {
            // The TestBase:HttpContextBase constructor will
            // create a HttpContext.Current if it is null  BLOGGED HERE
            HttpContext MockContext = HttpContext.Current;
 
            // Assert that we have a MockContext
            Assert.IsNotNull(MockContext, 
                "HttpContextBase should create HttpContext");
 
            // When the context is retrieved the PhysicalPath
            // property of our TestBase class will be set
            Assert.IsNotNull(PhysicalPath);
 
            // Dynamically generate our MockFolderPath using the 
            // TestBase:HttpContextBase.PhysicalPath property 
            MockFolderPath = PhysicalPath.Replace("default.aspx", "App_Data");
 
            // Instantiate our file Utility class
            FileUploadUtil fileUploadUtil = new FileUploadUtil();
 
            // Setup the TypeMock recorder
            // When MapPath("App_Data") is requested, supply our 
            // MockFolderPath (public static string in TestBase)
            using (RecordExpectations recorder = RecorderManager.StartRecording())
            {
                // GetTempFile() will request this - we'll return
                // our MockFolderPath when it does
                HttpContext.Current.Server.MapPath("App_Data");
                recorder.Return(MockFolderPath);
            }
 
            // Use the fileUploadUtil to get Temp file in App_Data\Temp
            string app_dataPath = fileUploadUtil.GetTempFile();
 
            // Write mockData to temp file using our string extension
            mockData.StrToFile(app_dataPath);
 
            // Ensure our mockData file exists so we can 
            // pull it into a MockStream
            Assert.IsTrue(File.Exists(app_dataPath));
 
            // Read temp file containing mockData into file stream
            FileInfo fileInfo = new FileInfo(app_dataPath);
            FileStream MockStream = fileInfo.OpenRead();
 
            // Instantiate our mock FileUpload control
            FileUpload MockFileUploadControl = new FileUpload();
 
            // Setup the TypeMock recorder 
            using (RecordExpectations recorder = RecorderManager.StartRecording())
            {
                // GetTempFile() will request this - we'll return
                // our MockFolderPath when it does
                HttpContext.Current.Server.MapPath("App_Data");
                recorder.Return(MockFolderPath);
 
                // When the contents from the PostedFile.InputStream is 
                // requested we'll return our MockStream (set above to
                // the contents of app_dataPath)
                recorder.ExpectAndReturn(
                    MockFileUploadControl.PostedFile.InputStream, 
                    MockStream);
            }
            // Call our FileUploadUtil method that will save the 
            // FileUpload control's contents to a temporary file
            string savedFile = fileUploadUtil
                .SaveFileUploadAsTempFile(MockFileUploadControl);
 
            // Retrieve the file just saved
            string savedXML = savedFile.FileToStr();
 
            // Assert that it is equal to the data that was in our
            // MockStream
            Assert.AreEqual(mockData, savedXML);
 
            MockManager.Verify();
        }
 
 
        private TestContext testContextInstance;
 
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }
    }
}
Source code available HERE Change Set: 40565

Tags: ,
Categories: CASKDotNet | TypeMock


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know