Home > database >  Table driven tests for private types with public constructors
Table driven tests for private types with public constructors

Time:10-23

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.

See https://github.com/golang/lint/issues/210

  • Related