简体   繁体   中英

Mocking File calls with Rhino Mock

Is it possible to mock out File calls with rhino mock example:

  private ServerConnection LoadConnectionDetailsFromDisk(string flowProcess)
  {
       var appPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
       var bodyFile = Path.Combine(appPath, @"XML\ServerConnections.xml");

        if (File.Exists(bodyFile))
        {
            //more logic
  }

So I am trying to mock the File.Exists method so it will return true, so I am able to test the next branch of logic regardless of if the file exists or not. Is this possible?

Here's your original snippet:

private ServerConnection LoadConnectionDetailsFromDisk(string flowProcess)
{
   var appPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
   var bodyFile = Path.Combine(appPath, @"XML\ServerConnections.xml");

    if (File.Exists(bodyFile))
    {
        //more logic
    }
}

Instead of using the System.IO library (which is not possible to mock), cadrell was basically saying to add a layer of abstraction, which you can mock:

private ServerConnection LoadConnectionDetailsFromDisk(string flowProcess)
{
   var appPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
   var bodyFile = Path.Combine(appPath, @"XML\ServerConnections.xml");

    if (FileExists(bodyFile))
    {
        //more logic
    }
}

public bool FileExists(bodyFile) { return File.Exists(bodyFile) }

Now, in your test, you can define a PartialMock that uses most of the existing code (allowing you to test it) but allows you to override just the FileExists method:

var myPartialMock = mockRepo.PartialMock(typeof(MyObject));

myPartialMock.Expect(m=>m.FileExists("")).IgnoreArguments().Return(true);

myPartialMock.LoadConnectionDetailsFromDisk("myProcess");

Now, the call from inside your if statement always returns true.

Something else to consider; I see an if block predicated on the existence of a file. You didn't specify the code, but I would bet anybody else but you (since you can change the code) that the code opens or manipulates the file we now know exists. So, the entire method rubs right up against the border of what you can and can't unit-test. You can consider refactoring this method to obtain a Stream from another function (allowing you to mock that function and inject a MemoryStream with test data), but at some point you'll be scraping the edges of your "sandbox" and will just have to trust that the .NET team did their job and that calls to File.Exists, File.Open etc work as expected.

Abstract it away using an interface.

public Interface IFileChecker
    {
       bool FileExists(string path)
    }

Then use the interface to create your mock object.

IFileChecker fileChecker = mocks.Stub<IFileChecker>();

using (mocks.Record())
            {
                fileChecker.Stub(i => i.FileExists(Arg<string>.Is.Any)).Return(true);
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM