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.
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.
public interface IStorage
{
bool StoreToFile(string path, string file, byte[] data);
}
public class Storage : IStorage
{
public bool StoreToFile( ... )
{
return WriteToFile( ... );
}
}
public class StorageMock : IStorage
{
public bool StoreToFile (...)
{
return false; //or true, depends on you test case
}
}
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)