C# 使用文件流模拟
我一直在尝试模拟使用文件流,但未能完成这一点,我不确定如何做到这一点,我使用rhino模拟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
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
?