Created
January 9, 2016 21:07
-
-
Save miklund/7360c81106ce7579b7b0 to your computer and use it in GitHub Desktop.
2011-10-27 Using TDD to test file system operations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FileSystemSynchronizer | |
{ | |
public void Synchronize(string source, string destination) | |
{ | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
{ | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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