Go unit test not finding required file

2.8k Views Asked by At

I have written a unit test in go and the init method of that same file opens a file in the root of the project. The problem that I am having is that when I run the test the package of the test is the root directory which does not contain the required file. How can I tell the test function to see the file without creating a duplicate file in the directory of the test file?

File structure:

main.go
|+-helpers
   |+-data.go
   |+-data_test.go
required_file.txt

Test command:

go test github.com/testproj/helpers

Code in data.go:

func init() {
    file, err := os.Open("required_file.txt") 
      if err != nil {
        log.Fatal(err) <-- required_file.txt not found
      }
}
1

There are 1 best solutions below

3
On

Your fundamental problem is that you have two different packages that are too tightly coupled. If you have a package which depends for its operation on a resource contained in another package, then really either:

  1. They shouldn't be two different packages; or
  2. You need to decouple them further.

So you have a number of alternatives, here:

  1. Just don't have a separate "helpers" package. If the functionality in that package has no purpose other than to help out with the main package, then combine them, since conceptually they're not independent enough to be distinct packages. As you're seeing, using folders simply as a means to organize code isn't as good an idea in Go as it can be in some other languages.

  2. Fully qualify the file name with an absolute path in both your main and your helpers packages. If it is really true that two independent packages depend on the same file, then they should both be able to find it regardless of where either package happens to be located, and that requires an absolute path. This is probably your least optimal solution.

  3. Further decouple the helpers package so that it doesn't depend on this file anymore, perhaps by:

    • computing a fully qualified file name in your main package and passing it to the functions in your helpers package when you call them;
    • opening the file in your main package, and passing an io.Reader to the file to the functions in your helpers package when you call them;
    • opening the file in your main package, and passing the contents of the file to the functions in your helpers package when you call them, perhaps as a bytes buffer; or
    • extract the information you need from the file in your main package, and pass only that relevant information to the functions in your helpers package when you call them.

Note that you're going to run into problems eventually with this approach anyway. When you run your main application, your current working directory will by default be whatever directory you are currently in when you execute the program. So unless you fully qualify the filename, then as soon as you run your application from any directory other than the one your source code is in, then it's not going to be able to find the required file, either.