C#(单元测试):我需要使其无法通过代码写入文件
基本上情况是这样的。我有以下内容:
public IService Service { get; set; } //Set to MyMockedService class.
public Boolean DoFoo()
{
//possible other ways of returning true/false...
Boolean success = true;
//Get FileInfo[] items
foreach (var item in items)
DoOtherFoo(item);
}
public Boolean DoOtherFoo(FileInfo fileInfo)
{
String filepath = //manipulate fileInfo.FullName;
Byte[] file = Service.GetFile(filepath)
try
{
WriteBinaryFile(filepath, file); //How can I force file writing to throw an exception
}
catch (Exception)
{
return false;
}
}
基本上,在测试 DoFoo() 时,我有很多可能返回 true/false 的路径。我已经对所有这些文件进行了单元测试,除了最后一个...它尝试写入文件,如果其中一个文件由于某种原因无法写入,它就会失败并返回 false。起初,我想如果我尝试设置一个错误的文件名,例如“bad*file”,它会在 WriteFile 中引发异常,但我什至没有做到这一点,因为我无法使用非法字符创建 FileInfo 对象。所以我正在寻找另一种方法来实现它,这样就不可能写入文件,这样我就可以返回错误。
Basically, here's the situation. I have the following:
public IService Service { get; set; } //Set to MyMockedService class.
public Boolean DoFoo()
{
//possible other ways of returning true/false...
Boolean success = true;
//Get FileInfo[] items
foreach (var item in items)
DoOtherFoo(item);
}
public Boolean DoOtherFoo(FileInfo fileInfo)
{
String filepath = //manipulate fileInfo.FullName;
Byte[] file = Service.GetFile(filepath)
try
{
WriteBinaryFile(filepath, file); //How can I force file writing to throw an exception
}
catch (Exception)
{
return false;
}
}
Basically, In testing DoFoo() I have a lot of paths that could return true/false. I've unit tested all of them except the final one... where it attempts to write the files and if even one of the files can't be written for some reason, it fails and sends back false. At first I figured if I tried to setup a bad filename such as "bad*file" it would throw an exception in the WriteFile but I didn't even get that far because I can't create a FileInfo object using illegal characters. So I'm looking for another way to make it so that it would be impossible to write the file so I can get back a false.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好的单元测试是孤立的。这意味着它们绝对独立于任何环境(文件、数据库、网络等)。如果你的代码使用文件来存储数据,你应该通过一些接口隐藏,生产和测试代码将使用不同的实现。生产实际上会写入文件,测试只会模拟它。
现在,在测试中,您可以用假实现“替代”真实实现。这称为嘲笑。
考虑到“控制反转”的设计。还有很多框架允许您通过依赖项注入使用“控制投资”(StructureMap、Ninject、Wisdor)
Good unit tests are isolated ones. It means they are absolutely idependent of any environment (files, database, network etc.). If your code uses files to store data in it, you should hide by some interface, the production and test code would use different implmementation. Production will really do Write to file, test one will only emulate it.
Now in tests you are able to "subtitue" real implmementaion with fake one. This is called mocking.
Desing that takes into considiration called "Inversion of Control". There are also a bunch of frameworks that allows you to use "Investion of Control" throught dependency injection (StructureMap, Ninject, Wisdor)
WriteBinaryFile
是同一个类
中的方法吗?您可以创建一个具有此唯一职责的对象,但从抽象开始:
现在您可以将此依赖项注入到您正在测试的类中,最好作为构造函数参数。
在您的应用程序中,您将使用
IBinaryFileWriter
的实现来完成当前方法的操作。不过,在测试中,您可以提供一个模拟,您可以将其配置为引发异常。
Is
WriteBinaryFile
a method in this sameclass
?You could create an object with this sole responsibility, but start with an abstraction:
Now you can inject this dependency into the class that you are testing, preferably as a constructor argument.
In your application, you'll use an implementation of
IBinaryFileWriter
that does exactly what your current method does.In tests, though, you can supply a mock that you can configure to throw an exception.
您的单元测试可以使用 System.IO.File.Open(...) 将
FileShare
设置为None
。任何其他进程都将无法打开该文件。Your unit test can use System.IO.File.Open(...) with
FileShare
set toNone
. Any other process will fail to open that file.这取决于 WriteBinaryFile 的内部结构。您需要在更细粒度的级别上测试 WriteBinaryFile。我认为这就是你的职责……我根本不认识这一点。
It depends on the internals of WriteBinaryFile. You need to be testing WriteBinaryFile at a more granular level. I assume that that's your function...I don't recognize that off the top of my head.
这是 FileInfo 的反编译代码
因此,在创建 FileInfo 后,您可以通过反射将 FullPath 和 OriginalPath 设置为无效文件路径,并使 WriteBinary 抛出异常,
就像这样:
Here is the decompiled code for ctor of FileInfo
So after creating a FileInfo you can set the FullPath and OriginalPath to an invalid filepath by reflection and make the WriteBinary throwing exceptoin
Just like that: