Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用文件流模拟_C#_Rhino Mocks - Fatal编程技术网

C# 使用文件流模拟

C# 使用文件流模拟,c#,rhino-mocks,C#,Rhino Mocks,我一直在尝试模拟使用文件流,但未能完成这一点,我不确定如何做到这一点,我使用rhino模拟 private Connection LoadConnectionDetailsFromDisk(string bodyFile) { //logic before using (FileStream fs = File.Open(bodyFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { ret

我一直在尝试模拟使用文件流,但未能完成这一点,我不确定如何做到这一点,我使用rhino模拟

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…)来模拟,以便我能够访问代码的这个分支吗?

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

private Connection LoadConnectionDetailsFromDisk(FileStream bodyFile)
{ 
  ....
}
如果你真的想要得到幻想,你总是可以接受一个IStream,然后模拟这个IStream,但是Rhino支持创建concreate类的模拟

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

您必须通过接口方法抽象
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
//创建一个模拟实例
var sourceMock=MockRepository.GenerateMock();
//设置期望值
Expect(m=>m.Open(“路径”,FileMode.Open,FileAccess.Read,FileShare.ReadWrite)
.回拨(
委托(字符串路径、文件模式、文件访问访问、文件共享)
{
//接电话
返回true;
}).重复.Any();
//TODO:取决于您触发LoadConnectionDetailsFromDisk方法调用的方式
//注入模拟
考虑到
LoadConnectionDetailsFromDisk()
您不能从测试中将mock直接注入此方法调用,因此请说明如何调用此方法。

您可以使用lib实现此目的。它包含包装系统类的接口和类,并允许您使用此类对方法进行单元测试。

还允许模拟
文件流

要使用它,首先必须稍微更改获取文件流的方式,例如:

private readonly IFileSystem _fileSystem; // this is from System.IO.Exception

// This is assuming dependency injection to insert the mock file system during testing, 
// or the real one in production
public YourConstructor(IFileSystem fileSystem)
{
   _fileSystem = fileSystem;
}

private Connection LoadConnectionDetailsFromDisk(string bodyFile)
{     
   using (Stream fs = _fileSystem.FileStream.Create(bodyFile, FileMode.Open))
   {
       return this.serverConfiguration.LoadConfiguration(fs, flowProcess);
   }

   //more logic
}

我通过创建一个
FileStream
子类来处理它。基本构造函数确实要求我们打开一个实际的文件,因此我将一个简单的文本文件设置为“Content”和“include if newer”,我们以只读和可共享的方式打开它

然后我覆盖了我实际需要的方法,在我的例子中,我需要write方法,并且我需要对所写的东西做些什么,所以我注入了一个回调来调用

private class CustomFileStream : FileStream
{
    private Action<string> WriteAction { get; }
    public CustomFileStream(Action<string> writeAction)
        // FileStream is notoriously hard to mock, so we inherit from it and we are a lightweight, real (but unused) FileStream underneath
        : base(Path.Combine(new ExecutionDirectory().Path /* Handle the execution directory in your own way */, "Content/DummyTextFile.txt"), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
    {
        this.WriteAction = writeAction;
    }

    public override bool CanWrite => true;
    public override void Write(ReadOnlySpan<byte> buffer)
    {
        this.WriteAction(Encoding.UTF8.GetString(buffer));
    }
}
private类CustomFileStream:FileStream
{
私有操作写操作{get;}
公共CustomFileStream(操作writeAction)
//众所周知,FileStream很难模仿,所以我们继承了它,并且我们是一个轻量级、真实(但未使用)的FileStream
:base(Path.Combine(new ExecutionDirectory().Path/*以自己的方式处理执行目录*/,“Content/DummyTextFile.txt”)、FileMode.Open、FileAccess.Read、FileShare.ReadWrite)
{
this.WriteAction=WriteAction;
}
public override bool CanWrite=>true;
公共重写无效写入(ReadOnlySpan缓冲区)
{
this.WriteAction(Encoding.UTF8.GetString(buffer));
}
}

在正常代码(测试之外)中如何调用
LoadConnectionDetailsFromDisk