Testing File System Operations in Rust with TempFile

My latest Rust project is using the file system to store snippets that are then loaded and interacted with using a snippet manager user interface.

I had created structs for the Snippet and the SnippetCollection and I wanted to write integration tests to test loading. I didn’t want to create a directory of test files since that would couple the tests to paths on my filesystem. After some searching I found the tempfile crate.

The tempfile crate worked perfectly for testing loading of the list collections. When I tried to load the individual snippet using file.read_to_string and make assertions about the content of the file the tests continually failed. The compiler displayed a message that the file could not be found.

After some failed attempts, and reading the documentation more closely this appears to be due to the file being garbage collected when the the file handle is closed.

I had opened a file handle to the temporary file to write the contents of the test file. I had placed this into it’s own function so that other tests could call it.

fn create_test_file()->String{
    let dir = tempdir().unwrap();
    let path=  dir.path().to_str().unwrap().to_string();


    let file_path = dir.path().join("a-php-file.php");
    let mut file = File::create(file_path).expect("Problem");
    writeln!(file, "<?php echo 'hello';?>").expect("Could not write");

    dir.path().join("a-php-file.php").into_os_string().into_string().unwrap()
}

The problem was that both dir and file were going out of scope and the temporary files were being deleted – as they should.

The solution, was to use a static and the lazy_static crate in the test.

#[macro_use]
extern crate lazy_static;

lazy_static!{
    static ref DIR:TempDir = tempdir().unwrap();
}

This created a static for DIR using the tempdir crate that could then be accessed in my create_test_file function as:

let path= DIR.path().to_str().unwrap().to_string();

The static ensured that the temporary directories and files were kept around until the end of the test execution and ensures that tests would pass.