project-layout
project-layout copied to clipboard
How to handle working directory change when using `go test`
If the main.go and mypackage_test.go don't reside in the same folder, I'm running into trouble when trying to open files while using relative paths.
In the following setup go run main.go fails while go test ./... is successful. I would like to have both work at the same time.
├── go.mod
├── main.go
└── mypackage
├── mypackage.go
├── mypackage_test.go
└── relativeFilePath
main.go
package main
import "github.com/3ter/testgostructure/mypackage"
func main() {
mypackage.MyOpen()
}
mypackage.go
package mypackage
import "os"
// MyOpen tries to open a relative path once with 'go run' and once with 'go test'
func MyOpen() {
_, err := os.Open("./relativeFilePath")
if err != nil {
panic("Relative path not found!")
}
}
mypackage_test.go
package mypackage
import "testing"
func TestAbs(t *testing.T) {
MyOpen()
}
Is there a standard way of dealing with this issue?
You should treat “./relativeFilePath” as a dependency for “mypackage”, either as a parameter passed to “MyOpen()”, or refactor MyOpen to be a method on a struct that has the path set as a field in the struct (with a useful default if unset). The behavior of MyOpen should be testable this way no matter how the package is used.
If I understand you correctly all relative paths should only be situated in the main package. This way they are always resolved correctly as the module root defined by the placement of go.mod is used as the reference for both testing and running.
This also makes sense as those file paths can be seen as dependencies to main or (sub)dependencies to other packages like mypackage in this example.