Mocking a Using with a FileStream

user101010101 picture user101010101 · Jun 21, 2012 · Viewed 14.7k times · Source

I have been trying to mock out a using with a file stream but have not been able to complete this and am unsure how to do it, I am using rhino mock.

private Connection LoadConnectionDetailsFromDisk(string bodyFile)
{     
   //logic before
   using (FileStream fs = File.Open(bodyFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
   {
     return this.serverConfiguration.LoadConfiguration(fs, flowProcess);
   }
    //more logic
}

Could anyone tell me how to mock the using(FileStream....) so I am able to access this branch of the code?

Answer

sll picture sll · Jun 21, 2012

You have to abstract File.Open() by an interface method then you would be able mocking call to it.

So

1) Create an interface:

public interface IFileDataSource
{
   FileStream Open(string path,
                   FileMode mode,
                   FileAccess access,
                   FileShare share);
}

2) Change LoadConnectionDetailsFromDisk() as following:

private Connection LoadConnectionDetailsFromDisk(string path, IFileDataSource fileSource)
{     
   using (FileStream fs = fileSource.Open(bodyFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
   {
      return this.serverConfiguration.LoadConfiguration(fs, flowProcess);
   }

   //more logic
}

3) In a test mock the interface and inject a mock

// create a mock instance
var sourceMock = MockRepository.GenerateMock<IFileDataSource>();

// setup expectation
sourceMock.Expect(m => m.Open("path", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
         .CallBack(
 delegate (string path, FileMode mode, FileAccess access, FileShare share)
 {
      // handle a call

     return true;
 }).Repeat.Any();

// TODO: depends on how you are triggering LoadConnectionDetailsFromDisk method call
// inject a mock

Considering that LoadConnectionDetailsFromDisk() you can not inject mock directly to this method call froma test so please show how this method is invoked.