Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create File During Unit Test - Can't Open it to Write - TestDriven.Net and NUnit

I'm testing some code that needs to use FileInfo and DirectoryInfo object and, instead of write a wrapper and several interfaces to solve this, I thought it would be a good idea create some files when starting the test and then delete those files after the test is done. This is the way I create the files:

public static void CreateTestSchedules(int quantity)
{
    String folder = Path.Combine(Directory.GetCurrentDirectory(), "FolderFiles");
    for(int quantity=10; quantity > 0; quantity--)
    {
       String filename = Path.GetTempFileName();
       using (FileStream fileStream = File.Create(Path.Combine(folder, filename)))
       {
            XDocument fileContent = Helper.CreateContent(filename);
            Byte[] bytes = ASCIIEncoding.ASCII.GetBytes(fileContent.ToString());

            fileStream.Write(bytes, 0, bytes.Length);
            fileStream.Flush();
            fileStream.Close();
        }
     }
}

At this point, I don't see a problem: the files are created under the folder and everything looks fine.

Then, when the execution of the test continues, I try to open one of those file to write something in it, and I get an exception indicating the file that I want to open for writing is being used by other process and, after checking with more detail, I see the TestDriven.Net process as the one blocking the file. This is the code I use to open and try to write data to the file:

using (FileStream file = new FileStream(filename, FileMode.Append))
{
    Byte[] bytes = ASCIIEncoding.ASCII.GetBytes(dataToWrite.ToString());
    if (file.CanWrite)
    {
        file.Write(bytes, 0, bytes.Length);
    }
}

My question is: why is this happening? am not releasing the file handle correctly? is there a away to steal the lock from TestDriven.Net? should I be creating this files differently? should I be writing the test in some other way?

Thanks in advance for the answers and comments =).

EDIT:

To solve THIS specific problem (the REAL problem, as Dave Swersky mentioned it, is that the Unit Test SHOULD NOT TOUCH the file system) I used the link sent by James Wiseman (thanks again James =) and created the file with a FileShare flag, that way I can reach into the file, open it an write to it. Like this:

 using (FileStream fileStream = new FileStream( filename, FileMode.Create, FileAccess.ReadWrite, **FileShare.ReadWrite**))

With that I can open and write the to the file. =)

like image 671
Hugo Avatar asked Oct 13 '22 18:10

Hugo


2 Answers

This probably isn't the answer you're looking for, but this is exactly why you should use mocks and not actually create files.

Here's a ready-made solution for mocking the file system: http://bugsquash.blogspot.com/2008/03/injectable-file-adapters.html

like image 99
Dave Swersky Avatar answered Nov 15 '22 09:11

Dave Swersky


I notice you're using the FileStream object directly to perform the writing.

Does the same problem present if you create a StreamWriter object, and use that for the file operations (including the close)?

A search on Google turned up this article. You may find it helpful. http://foson.blogspot.com/2007/10/closing-filestream-and-streamwriter-and.html

like image 26
James Wiseman Avatar answered Nov 15 '22 10:11

James Wiseman