gormtestutil

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 1, 2023 License: MIT Imports: 7 Imported by: 0

README

🦁 Gorm Test Utils

Go package GitHub GitHub go.mod Go version

Small utility functions for testing Gorm-related code. Such as sqlite database instantiation and wait groups with callbacks.

⬇️ Installation

go get github.com/ing-bank/gormtestutil

📋 Usage

Database Instantiation
package main

import (
	"testing"
	"github.com/ing-bank/gormtestutil"
)

func TestProductService_FetchAll_ReturnsAllProducts(t *testing.T) {
	// Arrange
    db := gormtestutil.NewMemoryDatabase(t,
		gormtestutil.WithName(t.Name()),
		gormtestutil.WithoutForeignKeys(),
		gormtestutil.WithSingularConnection())
	
    // [...]
}
Hooks
package main

import (
	"github.com/ing-bank/gormtestutil"
	"time"
	"testing"
)

func TestProductService_Create_CreatesProduct(t *testing.T) {
	// Arrange
	db := gormtestutil.NewMemoryDatabase(t)

	expectation := gormtestutil.ExpectCreated(t, db, Product{}, gormtestutil.WithCalls(1))

	// Act
	go Create(db, Product{Name: "Test"})

	// Assert
	gormtestutil.EnsureCompletion(t, expectation, gormtestutil.WithTimeout(30*time.Second))
}

🚀 Development

  1. Clone the repository
  2. Run make tools to install necessary tools
  3. Run make t to run unit tests
  4. Run make fmt to format code
  5. Run make lint to lint your code

You can run make to see a list of useful commands.

🔭 Future Plans

Nothing here yet!

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func EnsureCompletion

func EnsureCompletion(t testingi.T, wg *sync.WaitGroup, options ...EnsureOption) bool

EnsureCompletion ensures that the waitgroup completes within a specified duration or else fails

func ExpectCreated

func ExpectCreated(t testingi.T, database *gorm.DB, model any, options ...ExpectOption) *sync.WaitGroup

ExpectCreated asserts that an insert statement has at least been executed on the model.

Example (Defaults)

example where the default arguments are used (expect created once and no previous expectations) with an upper limit of test time

var t *testing.T

// arrange
type SomeModel struct {
	Name string
}

database := NewMemoryDatabase(t)
expectation := ExpectCreated(t, database, &SomeModel{})

// Act
_ = database.Create(SomeModel{Name: "Hello, world!"})

// Assert
if ok := EnsureCompletion(t, expectation); !ok {
	t.FailNow()
}
Output:

Example (WithVarArgs)

example where the default arguments are used (expect created once and no previous expectations) with an upper limit of test time

var t *testing.T
var exp *sync.WaitGroup

// arrange
type SomeModel struct {
	Name string
}

database := NewMemoryDatabase(t)
expectation := ExpectCreated(t, database, &SomeModel{}, WithCalls(2), WithExpectation(exp), WithoutMaximum())

// Act
_ = database.Create(SomeModel{Name: "Hello, world!"})
_ = database.Create(SomeModel{Name: "And another time"})

// Assert
if ok := EnsureCompletion(t, expectation, WithTimeout(15*time.Second)); !ok {
	t.FailNow()
}
Output:

func ExpectDeleted

func ExpectDeleted(t testingi.T, database *gorm.DB, model any, options ...ExpectOption) *sync.WaitGroup

ExpectDeleted asserts that a delete statement has at least been executed on the model.

func ExpectUpdated

func ExpectUpdated(t testingi.T, database *gorm.DB, model any, options ...ExpectOption) *sync.WaitGroup

ExpectUpdated asserts that an update statement has at least been executed on the model.

func NewMemoryDatabase

func NewMemoryDatabase(t testingi.T, options ...MemoryDatabaseOption) *gorm.DB

NewMemoryDatabase returns a sqlite database that runs in-memory, allowing you to use a database without a running instance. Multiple options can be passed to configure the database.

Example
type MyObject struct {
	ID int
}

t := new(testing.T)
database := NewMemoryDatabase(t)

var count int64
database.Model(&MyObject{}).Count(&count)
fmt.Printf("There are %d objects\n", count)
Output:

Example (IgnoringForeignKeys)
type MyObject struct {
	ID int
}

t := new(testing.T)
database := NewMemoryDatabase(t, WithoutForeignKeys())

var count int64
database.Model(&MyObject{}).Count(&count)
fmt.Printf("There are %d objects\n", count)
Output:

Example (WithSingularConnection)
type MyObject struct {
	ID int
}

t := new(testing.T)

database1 := NewMemoryDatabase(t, WithName(t.Name()))
database2 := NewMemoryDatabase(t, WithName(t.Name()))

database1.Create(&MyObject{ID: 2})

var result MyObject
database2.First(&result)
fmt.Println(result.ID)
Output:

Types

type EnsureOption

type EnsureOption func(*ensureConfig)

EnsureOption allows various options to be supplied to EnsureCompletion

func WithTimeout

func WithTimeout(timeout time.Duration) EnsureOption

WithTimeout is used to set a timeout for EnsureCompletion

type ExpectOption

type ExpectOption func(*expectConfig)

ExpectOption allows various options to be supplied to Expect* functions

func WithCalls

func WithCalls(times int) ExpectOption

WithCalls is used to expect an invocation an X amount of times

func WithExpectation

func WithExpectation(expectation *sync.WaitGroup) ExpectOption

WithExpectation allows you to chain wait groups and expectations together

func WithoutMaximum

func WithoutMaximum() ExpectOption

WithoutMaximum instructs the expectation to ignore an excess amount of calls. By default, any more calls than the expected 'times' cause an error.

type MemoryDatabaseOption

type MemoryDatabaseOption func(*memoryDbConfig)

MemoryDatabaseOption allows various options to be supplied to NewMemoryDatabase

func WithName

func WithName(name string) MemoryDatabaseOption

WithName gives the database a name, allowing you to use NewMemoryDatabase multiple times to connect to the same database instance.

func WithSingularConnection

func WithSingularConnection() MemoryDatabaseOption

WithSingularConnection is useful when you're getting 'database table is locked' errors while working with goroutines. This wil make sure sqlite only uses 1 connection.

func WithoutForeignKeys

func WithoutForeignKeys() MemoryDatabaseOption

WithoutForeignKeys disabled foreign keys for testing purposes

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL