问题 使用FileStream模拟使用


我一直试图模拟使用文件流,但无法完成这个,我不确定如何做到这一点,我正在使用犀牛模拟。

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
}

谁能告诉我如何模拟使用(FileStream ....)所以我能够访问代码的这个分支?


5764
2018-06-21 15:16


起源



答案:


你必须抽象 File.Open() 通过接口方法,您就可以模拟对它的调用。

所以

1)创建一个界面:

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

2)改变 LoadConnectionDetailsFromDisk() 如下:

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)在测试中模拟界面并注入模拟

// 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

考虑到这一点 LoadConnectionDetailsFromDisk() 你不能直接将mock注入这个方法调用froma test,所以请说明如何调用这个方法。


9
2018-06-21 15:23



我该怎么打电话 LoadConnectionDetailsFromDisk 在正常代码中(测试之外)? - jing


答案:


你必须抽象 File.Open() 通过接口方法,您就可以模拟对它的调用。

所以

1)创建一个界面:

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

2)改变 LoadConnectionDetailsFromDisk() 如下:

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)在测试中模拟界面并注入模拟

// 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

考虑到这一点 LoadConnectionDetailsFromDisk() 你不能直接将mock注入这个方法调用froma test,所以请说明如何调用这个方法。


9
2018-06-21 15:23



我该怎么打电话 LoadConnectionDetailsFromDisk 在正常代码中(测试之外)? - jing


您可以使用 SystemWrapper 用于此目的的lib。它包含包装系统类的接口和类,并使您能够使用此类对单元测试方法进行单元化。


1
2017-07-24 07:59





我将重构该方法,以便将FileStream传递给该方法,以便您可以创建文件流的模拟

private Connection LoadConnectionDetailsFromDisk(FileStream bodyFile)
{ 
  ....
}

如果你真的想要获得幻想,你可以随时接受一个I​​Stream,然后模拟那个IStream,但Rhino支持创建模拟混合类

 MockRepository mocks = new MockRepository();
 FileStream basket = mocks.CreateMock<FileStream>();

0
2018-06-21 15:22