patterncsharpMinor
Writing to a newly created file, with support for unit testing
Viewed 0 times
filecreatedwithwritingtestingforunitsupportnewly
Problem
When now increasingly making code unit testable, I notice that code gets bloated, only to get dependencies out. A simple file operation, like saving a file, and, if a file with the name already exists, append a numeric index, can become greatly bloated by this.
I understand that writing real files in a unit test is not a good choice, but isn't it better to avoid too much code bloat for decoupling? Also, the simple version can be static, while the testable one requires instantiation.
The function is likely to never save anything other than files, never any database entry, network resource or whatever.
The decoupled version, with two classes and IIoProvider interface, is much too long for my taste, compared to the simple version with System.IO dependency.
```
///
/// Unit testable version
///
public class FileWithIndexSaverBloated
{
private readonly IIoProviderBloat _ioProvider;
public FileWithIndexSaverBloated()
{
_ioProvider = new FileIoProviderBloat();
}
///
/// Mocking/testing only
///
/// Any IIoP
I understand that writing real files in a unit test is not a good choice, but isn't it better to avoid too much code bloat for decoupling? Also, the simple version can be static, while the testable one requires instantiation.
The function is likely to never save anything other than files, never any database entry, network resource or whatever.
///
/// Save file with given name, or with underscore and next free numeric ending,
/// if already existing. Bound to System.IO file operations.
///
public static class FileWithIndexSaverSimple
{
public static string SaveFileWithNumberIfExisting(string pathName, string content)
{
string pathNameNoExt = Path.Combine(
Path.GetFullPath(pathName),
Path.GetFileNameWithoutExtension(pathName));
string dotExtension = "." + Path.GetExtension(pathName);
string newFileName = pathNameNoExt + dotExtension;
int index = 0;
while (File.Exists(newFileName))
{
index++;
newFileName = pathNameNoExt + "_" + index + dotExtension;
}
using (var writer = new StreamWriter(File.Create(newFileName)))
{
writer.Write(content);
writer.Flush();
}
return newFileName;
}
}The decoupled version, with two classes and IIoProvider interface, is much too long for my taste, compared to the simple version with System.IO dependency.
```
///
/// Unit testable version
///
public class FileWithIndexSaverBloated
{
private readonly IIoProviderBloat _ioProvider;
public FileWithIndexSaverBloated()
{
_ioProvider = new FileIoProviderBloat();
}
///
/// Mocking/testing only
///
/// Any IIoP
Solution
You could write your own
System.IO interfaces and use them to wrap the classes from the namespace, but why reinvent the wheel? Go install the System.IO.Abstractions nuget package in your project and call it a day.Context
StackExchange Code Review Q#114452, answer score: 8
Revisions (0)
No revisions yet.