1

I want to create a test for the following function which creates a file at a particular path:

    exists, err := IsFileExists(path)
    if err != nil {
        return err
    }
    if exists {
        return errors.New("File already exists")
    }
    file, err := os.Create(path)
    defer file.Close()
    return err

I know in JUnit there's the TemporaryFolder rule to help you set up the file and directory structure you need for your test like so:

public class DummyFileClassTest {
    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    @Test
    public void someMethod() {
        // given
        final File file1 = folder.newFile("myfile1.txt");
        final File file2 = folder.newFile("myfile2.txt");

        ... etc...
    }
}

Is there something similar in Go? Or a better approach?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
dev_ab
  • 43
  • 6
  • 3
    Checking if a file exists and creating it if it doesn't is a ["race condition"](https://en.wikipedia.org/wiki/Race_condition). If two processes do that at the same time they may both conclude there's no file and both try to create it. Instead, try to create it and look for an error. Instead of "check then do", "do then check". – Schwern Jan 03 '21 at 20:15
  • Right, makes sense! I will "do then check" as you mention. But, to do that would you recommend me to use [ioutil.TempDir](https://golang.org/pkg/io/ioutil/#TempDir) to: Create a Temporary Directory, create the files there, check if they were created and then erase the Temporary Directory? – dev_ab Jan 03 '21 at 20:26
  • do you have already see this https://stackoverflow.com/q/16742331/2270041 ? – Matteo Jan 03 '21 at 21:12

1 Answers1

4

testing provides TempDir to get a test directory which will be cleaned up after each test.

import(
  "testing"
  "path"
)

func TestConvert(t *testing.T) {
    tmpdir := t.TempDir()
 
    ...

    // tmpdir will be cleaned up
}

You can then do path.Join(tmpdir, "test.file") to make a file with a specific name in the temp directory, or ioutil.TempFile(tmpdir, "*") to make a random one.


Note, your function contains a race condition. If two processes both check for the file at the same time they will both conclude it does not exist and both try to create the file. One will create the file, the other will truncate it. This is "check then do".

Instead, create the file and then check for an error. "Do then check".

Schwern
  • 153,029
  • 25
  • 195
  • 336