Abstracting test utilities inside integration test files

InstructorChris Biscardi

Share this video with your friends

Send Tweet

While we have test_write_with_title which tests the garden CLI with a given title flag, we can also set up additional tests, such as for using a written title in the document for the filename.

Copy/pasting the code from test one into test two is a lot of duplication, and setting up the fake editor isn't going to change across tests, so let's abstract the creation of the temporary directory, the fake editor script path, and the Command itself into a utility function.

The port is relatively straightforward, with the only changes being that we cut off the cmd modifications before the .arg calls, and now have to return the cmd and the temp_dir in a tuple.

We return the actual Command and TempDir, yielding ownership to the calling function because we have no further use for them here, but the calling function will need to mutate the Command more, and use TempDir to test.

fn setup_command() -> (Command, assert_fs::TempDir) {
    let temp_dir = assert_fs::TempDir::new().unwrap();

    let mut cmd = Command::cargo_bin("garden").unwrap();
    let fake_editor_path = std::env::current_dir()
        .expect("expect to be in a dir")
        .join("tests")
        .join("fake-editor.sh");
    if !fake_editor_path.exists() {
        panic!(
            "fake editor shell script could not be found"
        )
    }

    cmd.env("EDITOR", fake_editor_path.into_os_string())
        .env("GARDEN_PATH", temp_dir.path());
    (cmd, temp_dir)
}

The new write tests are considerably shorter now and focus mostly on which subcommand to call, and what the user interaction with that subcommand is.


fn test_write_with_title() {
    let (mut cmd, temp_dir) = setup_command();
    let assert = cmd
        .arg("write")
        .arg("-t")
        .arg("atitle")
        .write_stdin("N\n".as_bytes())
        .assert();

    assert.success();

    temp_dir
        .child("atitle.md")
        .assert(predicate::path::exists());
}

fn test_write_with_written_title() {
    let (mut cmd, temp_dir) = setup_command();
    let assert = cmd
        .arg("write")
        .write_stdin("N\n".as_bytes())
        .assert();

    assert.success();

    temp_dir
        .child("testing.md")
        .assert(predicate::path::exists());
}