Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save miklund/7360c81106ce7579b7b0 to your computer and use it in GitHub Desktop.
Save miklund/7360c81106ce7579b7b0 to your computer and use it in GitHub Desktop.
2011-10-27 Using TDD to test file system operations
# Title: Using TDD to test file system operations
# Author: Mikael Lundin
# Link: http://blog.mikaellundin.name/2011/10/27/unit-test-file-system-operations.html
public class FileSystemSynchronizer
{
public void Synchronize(string source, string destination)
{
}
}
public class FileSystemSynchronizer
{
private readonly IFileSystemFactory fsFactory;
public FileSystemSynchronizer(IFileSystemFactory fsFactory)
{
this.fsFactory = fsFactory;
}
public void Synchronize(string sourcePath, string targetPath)
{
if (!fsFactory.PathExists(targetPath))
{
fsFactory.MakeDirectory(targetPath);
}
}
}
public class FileSystemSynchronizer
{
private readonly IFileSystemFactory fsFactory;
public FileSystemSynchronizer(IFileSystemFactory fsFactory)
{
this.fsFactory = fsFactory;
}
public void Synchronize(string sourcePath, string targetPath)
{
if (!fsFactory.PathExists(targetPath))
{
fsFactory.MakeDirectory(targetPath);
}
foreach (var file in fsFactory.GetDirectory(sourcePath).Files)
{
file.CopyTo(targetPath);
}
}
}
public class FileSystemSynchronizerSpecification
{
[Fact]
public void ShouldCreateTargetFolderIfDoesNotExist()
{
}
[Fact]
public void ShouldCopyAnyFilesFromSourceFolderToTargetFolder()
{
}
[Fact]
public void ShouldCopyAnyDirectoriesFromSourceFolderToTargetFolder()
{
}
[Fact]
public void ShouldCopyFilesAndFoldersRecursivlyFromSourceToTargetFolder()
{
}
[Fact]
public void ShouldNotCopySourceFileIfSameFileExistInTargetFolder()
{
}
[Fact]
public void ShouldCopySourceFileIfNewerThanFileInTargetFolder()
{
}
[Fact]
public void ShouldRemoveFilesFromTargetFolderNotPresentInSourceFolder()
{
}
}
[Fact]
public void ShouldCreateTargetFolderIfDoesNotExist()
{
const string SourcePath = @"C:\FolderA";
const string TargetPath = @"C:\FolderB";
/* Setup */
var factory = MockRepository.GenerateMock<IFileSystemFactory>();
var sut = new FileSystemSynchronizer(factory);
/* Arrange */
factory.Expect(f => f.PathExists(TargetPath)).Return(false);
/* Test */
sut.Synchronize(SourcePath, TargetPath);
/* Assert */
factory.AssertWasCalled(f => f.MakeDirectory(TargetPath));
}
[Fact]
public void ShouldCopyAnyFilesFromSourceFolderToTargetFolder()
{
/* Setup */
var factory = MockRepository.GenerateMock<IFileSystemFactory>();
var sut = new FileSystemSynchronizer(factory);
var targetDirectory = MockRepository.GenerateStub<IDirectory>();
var file1 = MockRepository.GenerateMock<IFile>();
file1.Name = "first.txt";
var file2 = MockRepository.GenerateMock<IFile>();
file2.Name = "second.txt";
var fileList = new[] { file1, file2 };
/* Arrange */
factory.Expect(f => f.PathExists(TargetPath)).Return(true);
factory.Expect(f => f.GetDirectory(SourcePath)).Return(targetDirectory);
targetDirectory.Files = fileList;
/* Test */
sut.Synchronize(SourcePath, TargetPath);
/* Assert */
foreach (var file in fileList)
{
file.AssertWasCalled(f => f.CopyTo(TargetPath));
}
}
[Fact]
public void ShouldCreateTargetFolderIfDoesNotExist()
{
const string UnknownTargetPath = @"C:\FolderC";
/* Setup */
var factory = new VirtualFileSystemFactory();
var sut = new FileSystemSynchronizer(factory);
/* Test */
sut.Synchronize(SourcePath, UnknownTargetPath);
/* Assert */
Assert.True(factory.PathExists(UnknownTargetPath), "Target path should be created if it does not exist");
}
[Fact]
public void ShouldCopyAnyFilesFromSourceFolderToTargetFolder()
{
/* Setup */
var factory = new VirtualFileSystemFactory();
var sut = new FileSystemSynchronizer(factory);
// Create files in source folder
var sourceFolder = factory.GetDirectory(SourcePath);
sourceFolder.Add(new VirtualFile("first.txt"));
sourceFolder.Add(new VirtualFile("second.txt"));
/* Test */
sut.Synchronize(SourcePath, TargetPath);
/* Assert */
var targetFolder = factory.GetDirectory(TargetPath);
foreach (var file in sourceFolder.Files)
{
Assert.Contains(file, targetFolder.Files);
}
}
public class VirtualFileSystemFactory : IFileSystemFactory
{
public static readonly IDirectory FolderA;
public static readonly IDirectory FolderB;
private const string FolderAPath = @"C:\FolderA";
private const string FolderBPath = @"C:\FolderB";
private readonly IDictionary<string, IDirectory> fileSystem = new Dictionary<string, IDirectory>
{
{ FolderAPath, FolderA },
{ FolderBPath, FolderB },
};
static VirtualFileSystemFactory()
{
FolderA = new VirtualFolder(FolderAPath);
FolderB = new VirtualFolder(FolderBPath);
}
public bool PathExists(string targetPath)
{
return fileSystem.ContainsKey(targetPath);
}
public void MakeDirectory(string targetPath)
{
fileSystem.Add(targetPath, new VirtualFolder(targetPath));
}
public IDirectory GetDirectory(string sourcePath)
{
if (!this.PathExists(sourcePath))
{
throw new DirectoryNotFoundException("Folder was not registered in VirtualFileSystemFactory: " + sourcePath);
}
return fileSystem[sourcePath];
}
public void Copy(IFile file, string targetPath)
{
this.GetDirectory(targetPath).Add(file);
}
}
public class VirtualFile : IFile
{
public VirtualFile(string name)
{
Name = name;
}
public string Name { get; set; }
}
public class VirtualFolder : IDirectory, IEnumerable<IFileSystemItem>
{
private readonly string path;
private readonly IList<IFileSystemItem> items;
public VirtualFolder(string path)
{
this.path = path;
items = new List<IFileSystemItem>();
}
public IEnumerable<IFile> Files
{
get { return items.Where(f => f is IFile).Cast<IFile>(); }
}
public void Add(IFile file)
{
items.Add(file);
}
public IEnumerator<IFileSystemItem> GetEnumerator()
{
return items.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return items.GetEnumerator();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment