Originally posted on: http://geekswithblogs.net/akraus1/archive/2013/12/28/154992.aspx
Yes I know. If a unit test accesses a file it is by definition no longer a unit test. My personal definition of a unit test is: If it is fast I can run many of them which is ok for the main goal of unit tests to provide fast feedback. Personally I am not big fan of repetitive code so I created a small class that takes care of creating a temp folder in the %TEMP%\utest\ directory which creates a directory named after your unit test method name which is quite handy for debugging failed unit tests.
[Test]publicvoid Can_Create_Temp_Folder() {using (var tmp = TempDir.Create()) { var txtfile = Path.Combine(tmp.Name, "test.text"); File.WriteAllText(txtfile, "hi"); } }
This will give you a fresh directory for every test
which is deleted after the using statement has been left including its contents. You can create variations of that to e.g. leave the temp files in place when the unit test fails to make debugging easier (See here how to check in a finally block if you are in an exception unwind scenario). Or you can postfix every test with a guid to allow 100% separation of concurrently running unit tests and to make absolutely sure that you are not reusing old data of an unit test which had some files opened which could not be deleted last time. The simplest form is a small code snippet like this:
interface ITempDir : IDisposable {string Name { get; } }class TempDir : ITempDir {publicstring Name { get;private set; }/// <summary>/// Create a temp directory named after your test in the %temp%\uTest\xxx directory/// which is deleted and all sub directories when the ITempDir object is disposed./// </summary>/// <returns></returns> [MethodImpl(MethodImplOptions.NoInlining)]publicstatic ITempDir Create() { var stack = new StackTrace(1); var sf = stack.GetFrame(0);returnnew TempDir(sf.GetMethod().Name); }public TempDir(string dirName) {if( String.IsNullOrEmpty(dirName)) {thrownew ArgumentException("dirName"); } Name = Path.Combine(Path.GetTempPath(), "uTests", dirName); Directory.CreateDirectory(Name); }publicvoid Dispose() {if( Name.Length<10) {thrownew InvalidOperationException(String.Format("Directory name seesm to be invalid. Do not delete recursively your hard disc.", Name)); }// delete all files in temp directoryforeach(var file in Directory.EnumerateFiles(Name, "*.*", SearchOption.AllDirectories)) { File.Delete(file); }// and then the directory Directory.Delete(Name,true); } }
Small, simple but effective.