I have an application that takes a dictionary of files (file type, and list of file names) and copies the files from the original directory into another location.
I’ve already got the basic code for the copy process, but I need to do some unit tests so it is as robust as possible.
I have wrapper class that I am using so I can test that the System.IO methods are called as I expect, but I am having some difficulty figuring out how to form the tests as there are foreach and switch statements in the code.
Sample code below:
private IFileSystemIO _f;
public CopyFilesToDestination(IFileSystemIO f){
_f = f;
}
public void Cpy_Files(Dictionary<string, List<string>> files)
{
// get a list of the file types in the directory
var listOfFileTypes = new List<string>(files.Keys);
foreach (var fileType in listOfFileTypes){
var fileList = files[fileType].ToList();
foreach (var file in fileList){
switch(fileType){
case ".txt":
_f.Copy(file, @"c:\destination\text");
break;
case ".dat":
_.Copy(file, @"c:\destination\data");
break;
}
}
}
}
To test the above I had thought I would use a mock dictionary object, set up with a list of file types and paths:
public virtual Dictionary<string, List<string>> FakeFiles(){
return fakeDictionary = new Dictionary<string, List<string>>(){
{".txt", new List<string>(){
"c:\test\file1.txt",
"c:\test\file2.txt"
}
},
{".dat", new List<string>(){
"c:\test\file1.dat",
"c:\test\file2.dat"
}
};
}
}
The first test I came up with looks like this:
[Test]
public void Should_Copy_Text_Files(){
var dictionary = new FakeDictionary().FakeFiles();
var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
var systemUnderTest = new CopyFileToDestination(mockObject);
systemUnderTest.Cpy_Files(dictionary);
// I think this means "test the operation, don't check the values in the arguments" but I also think I'm wrong
mockObject.AssertWasCalled(f => f.Copy("something", "something"), o => o.IgnoreArguments());
}
My first problem is: How do I test for a specific file type, such as “.txt”?
Then how do I test the loops? I know with the mocked dictionary that I only have two items, do I leverage this to form the test? How?
I think I may be close to a solution, but I am running out of time/patience hunting it down. Any help is greatly appreciated.
Thanks
Jim
I tried using Roberts solution, but as I stated, I have too many different file types to set up each test case individually. The next thing I tried was setting up a TestCaseSource, but every time I ran the test for that it marked the test as ignored:
The data source is below:
What I finally worked out uses the times to repeat option in Rhino and is really pretty simple:
I hope this helps someone else with a similar problem.