Mocking VirtualFiles

I have a service that is using an upload service that we wrote. The upload service gets the files from Request.Files and then adds them to VirtualFiles. I am not certain how to mock this when testing my other service. Any advice or guidelines would be helpful. Here is what I have so far:

IHttpFile httpFile = new HttpFile { ContentType = "application/x-msaccess", FileName = "C:\\Tutorial Data\\CompanyC.mdb", ContentLength = };
        MockHttpRequest mockRequestContext = new MockHttpRequest {Files = new IHttpFile[] { httpFile }};

        for (int i = 0; i < mockRequestContext.Files.Length; i++)
        {
            IHttpFile file = mockRequestContext.Files[i];

            string fileId = Guid.NewGuid().ToString();
            string filename = UploadUtils.GetFileName(sessionId, fileId);
            uploadFilesService.VirtualFiles.WriteFile(filename, file.InputStream);
        }

However, I get a null exception error in the last line “Value cannot be null” parameter input.

Thanks for your time.

Note Uploaded HttpFiles on the Request and VirtualFiles in the Virtual FileSystem are completely different, you’ll need to configure them both, with the HttpFile you also need to populate its InputStream which is how the contents of the file are read (which you’re also accessing with file.InputStream).

Since you’re using VirtualFiles you’ll need to execute it within the scope of a populated AppHost. I’ve provided an example of mocking an uploaded file in this commit:

using (new BasicAppHost {
    ConfigureAppHost = host => 
        host.VirtualFiles = new InMemoryVirtualPathProvider(host),
}.Init())
{
    var ms = new MemoryStream("mocked".ToUtf8Bytes());
    var httpFile = new HttpFile {
        ContentType = "application/x-msaccess", FileName = "file.txt",
        InputStream = ms, ContentLength = ms.ToArray().Length,
    };
    var mockReq = new MockHttpRequest {
        Files = new IHttpFile[] { httpFile },
    };
    //Mock Session
    mockReq.Items[Keywords.Session] = new AuthUserSession { Id = "sess-id" };

    var service = new UploadFileService { Request = mockReq };
    service.Any(new MockUploadFile());

    var files = HostContext.VirtualFiles.GetAllFiles().ToList();
    Assert.That(files[0].ReadAllText(), Is.EqualTo("mocked"));
}

Example of Service implementation that processes Uploaded files which this test mocks:

public class MockUploadFile { }

public class UploadFileService : Service
{
    public object Any(MockUploadFile request)
    {
        for (int i = 0; i < Request.Files.Length; i++)
        {
            var file = Request.Files[i];

            string fileId = Guid.NewGuid().ToString();
            var session = base.GetSession();
            var fileName = session.Id.CombineWith(fileId);
            VirtualFiles.WriteFile(fileName, file.InputStream);
        }

        return request;
    }
}

But I’d consider doing an proper integration test for stuff like this, as you’ll be testing handling real file uploads and it would require similar configuration/effort so I don’t see the value of trying to mock this instead.