Testing with a Database
Some tests need a real database, for example to run commands from end to end. To get one, call the Store function with a *testing.T, the source, and the schemas to register. It returns a store on a database that all tests of the package share, which the first test that asks for it starts in a container:
func TestAcquireBook(t *testing.T) {
store := architecturekittest.Store(t, "https://library.eventsourcingdb.io", bookState.Schemas())
_, err := architecturekit.Execute(context.TODO(), store, acquireBook, AcquireBook{
BookID: uuid.NewString(),
// ...
})
if err != nil {
t.Fatal(err)
}
}
To stop the database once all tests have run, call the Main function from TestMain:
func TestMain(m *testing.M) {
architecturekittest.Main(m)
}
If TestMain has more to do once the tests have run, such as closing a browser, run the tests yourself, and call the StopSharedDatabase function afterwards. It does nothing if no test has started the database:
func TestMain(m *testing.M) {
code := m.Run()
closeBrowser()
if err := architecturekittest.StopSharedDatabase(); err != nil {
fmt.Fprintln(os.Stderr, err)
code = 1
}
os.Exit(code)
}
The tests share the events as well, so a test writes to subjects of its own, for example with a random ID in them, and reads only from those. A test that reads more than that, such as a projection from /, needs a database of its own. Call the IsolatedStore function to start one for the test alone, which is stopped once the test is over. It takes a few seconds, so use it only where the shared one would not do.
For a test that connects by itself, such as one that starts a whole server, call the SharedDatabase or the IsolatedDatabase function. Each returns a *Database, whose URL and APIToken fields are what a client needs. Its Client function returns a client, for example to write an event that no command would, and its Store function returns a store, as above:
database := architecturekittest.SharedDatabase(t)
config := server.Config{
DatabaseURL: database.URL.String(),
APIToken: database.APIToken,
}
Note that with -short every test that asks for a database is skipped, so that the other tests run without Docker.