Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func LoadScenario ¶
LoadScenario reads a YAML "scenario" file and uses it to populate the given db. Top-level keys in the YAML are treated as table names having repeated rows, where keys on each row are column names. For example:
users: - id: 1 name: Alice email: alice@example.com - id: 2 name: Bob email: bob@example.com posts: - user_id: 1 title: Hello, world! - user_id: 2 title: Goodbye, world! is_draft: true
The above would populate the users and posts tables. Fields that are missing from the YAML are left out of the INSERT statement, and so are populated with the default value for that column.
func RunMigrations ¶
RunMigrations reads all of the files matching *.up.sql in migrationDir and executes them in lexicographical order against the provided db. A typical convention is to use a numeric prefix for each new migration, e.g.:
001_create_users.up.sql 002_create_posts.up.sql 003_create_comments.up.sql
Note that this function does not check whether the migration has already been run. Its primary purpose is to initialize a test database.
Types ¶
type PostgresContainer ¶
type PostgresContainer struct {
// contains filtered or unexported fields
}
PostgresContainer is a Docker container running Postgres. It can be used to cheaply start a throwaway Postgres instance for testing.
func StartPostgresContainer ¶
func StartPostgresContainer(ctx context.Context, version string) (*PostgresContainer, error)
StartPostgresContainer starts a new Postgres Docker container. The version parameter is the tagged version of Postgres image to use, e.g. to use postgres:12 pass "12". Creation involes a few steps:
1. Pull the image if it isn't already cached locally 2. Start the container 3. Wait for Postgres to be healthy
Once created the container will be immediately usable. It should be stopped with the Shutdown method. The container will bind to a randomly available host port, and random password. The SQL connection string can be obtained with the ConnectionString method.
Container startup and shutdown together can take a few seconds (longer when the image has not yet been pulled.) This is generally too slow to initiate in each unit test so it's advisable to do setup and teardown once for a whole suite of tests. TestMain is one way to do this, however because of Golang issue 37206 1, panics in tests will immediately exit the process without giving you the opportunity to Shutdown, which results in orphaned containers lying around.
Another approach is to write a single test that starts and stops the container and then run sub-tests within there. The testify 2 suite package provides a good way to structure these kinds of tests:
type ExampleTestSuite struct { suite.Suite } func (s *ExampleTestSuite) TestExample() { // test something } func TestExampleTestSuite(t *testing.T) { pg, _ := sqltestutil.StartPostgresContainer(context.Background(), "12") defer pg.Shutdown(ctx) suite.Run(t, &ExampleTestSuite{}) }
func (*PostgresContainer) ConnectionString ¶
func (c *PostgresContainer) ConnectionString() string
ConnectionString returns a connection URL string that can be used to connect to the running Postgres container.
type Suite ¶
type Suite struct { suite.Suite // Context is a required field for constructing a Suite, and is used for // database operations within a suite. It's public because it's convenient to // have access to it in tests. context.Context // DriverName is a required field for constructing a Suite, and is used to // connect to the underlying SQL database. DriverName string // DataSourceName is a required field for constructing a Suite, and is used to // connect to the underlying SQL database. DataSourceName string // contains filtered or unexported fields }
Suite is a testify suite 1 that provides a database connection for running tests against a SQL database. For each test that is run, a new transaction is started, and then rolled back at the end of the test so that each test can operate on a clean slate. Here's an example of how to use it:
type ExampleTestSuite struct { sqltestutil.Suite } func (s *ExampleTestSuite) TestExample() { _, err := s.Tx().Exec("INSERT INTO foo (bar) VALUES (?)", "baz") s.Assert().NoError(err) } func TestExampleTestSuite(t *testing.T) { suite.Run(t, &ExampleTestSuite{ Suite: sqltestutil.Suite{ Context: context.Background(), DriverName: "pgx", DataSourceName: "postgres://localhost:5432/example", }, }) }
func (*Suite) SetupSuite ¶
func (s *Suite) SetupSuite()
func (*Suite) TearDownSuite ¶ added in v1.0.1
func (s *Suite) TearDownSuite()
func (*Suite) TearDownTest ¶
func (s *Suite) TearDownTest()