I'm trying to reduce the surface area of my API, so I made my app
struct non-exported (with the lowercase name), and only exposed the New
function:
package mylib
type app struct {
}
func New() *app {
return &app{}
}
But now, I want to write a table-driven test for this thing, and I can't hold a mylib.app
in a struct:
package mylib_test
import (
"testing"
"mylib"
)
func TestApp(t *testing.T) {
tests := []struct {
name string
app private_type_public_new.app // This part doesn't work
}{
// ...
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
})
}
}
What options do I have? Should I make the app struct public (App
) and leave all the fields unexported? Is there something interesting I can do with higher order functions to store instances of the New
function to instantiate apps within the subtests? Something else?
CodePudding user response:
What options do I have? Should I make the app struct public (App) and leave all the fields unexported?
Yes, export it as App
. golang/lint
(now deprecated) specifically warned about exported functions that referenced unexported types, as they are difficult for consumers of your package to work with. For example, if you assign x := mylib.New()
such that x
is an instance of *myapp.app
, go-pls
will show nothing about this variable except its type, meaning any descriptive comment you've attached to it will not appear.