An assertion package with a minimal API, yet powerful enough to cover most use cases.
The assert package is designed to provide a more configurable and type-safe alternative to the popular testify/assert package.
Have you ever struggled with comparing complex structs in your tests? One that use decimal.Decimal, time.Time, or uuid.UUID types? Or perhaps you wanted to ignore automatically generated fields, such as ID or CreatedAt, in your struct comparisons?
assert allows for more flexible assertions, such as ignoring unexported fields or skipping empty fields in struct comparisons.
package main
import (
"errors""fmt""io""io/fs""testing""github.com/krhubert/assert"
)
funcTestXYZ(t*testing.T) {
// assert checks if value implements Equal() bool method// and uses it to compare values. This makes it possible// to compare e.g. time.Time values.now:=time.Now()
assert.Equal(t, now, now)
// assert is type safe, so this will not compile// assert.Equal(t, 1, "1")// assert do not compare pointers, but values they point toa, b:=1, 1assert.Equal(t, &a, &b)
// assert checks for errorsassert.Error(t, errors.New("error"))
assert.NoError(t, nil)
// assert checks if error contains a target value// like string, error or structerr:=fmt.Errorf(
"closed socket: %w %w",
io.EOF,
&fs.PathError{Op: "read", Path: "socket", Err: io.ErrClosedPipe},
)
assert.ErrorContains(t, err, "closed socket")
assert.ErrorContains(t, err, io.EOF)
varpathError*fs.PathErrorassert.ErrorContains(atb, err, &pathError)
// assert checks if function panics or notassert.Panic(t, func() { panic(0) })
assert.NotPanic(t, func() { })
// assert can be used to check errors in defer functionsdeferassert.Defer(t, func() error { returnfile.Close() })()
// assert can be used to check if a value is of a specific typegs:=TypeAssert[fmt.GoStringer](t, time.Time{})
}package main
import (
"errors""fmt""io""io/fs""testing"
_ "github.com/mattn/go-sqlite3""go.uber.org/mock/gomock""github.com/krhubert/assert"
)
typeExampleTestSuitestruct {
assert.Suiteiintctrl*gomock.Controllerdb*sql.DB
}
func (s*ExampleTestSuite) Setup(t*testing.T) {
s.i=4s.ctrl=gomock.NewController(t)
db, err:=sql.Open("sqlite3", ":memory:")
assert.NoError(t, err)
s.db=db
}
func (s*ExampleTestSuite) Teardown(t*testing.T) {
s.i=0assert.NoError(t, s.db.Close())
}
funcTestExample(t*testing.T) {
ts:= assert.Setup[ExampleTestSuite](t)
row:=ts.db.QueryRow("select date()")
vardatestringassert.NoError(ts, row.Scan(&date))
assert.NoError(ts, row.Err())
}package assert
import (
"testing""time""github.com/google/uuid""github.com/shopspring/decimal""github.com/stretchr/testify/require"
)
funcTestExampleEqual(t*testing.T) {
typeUserstruct {
Id uuid.UUIDEmailstringCreatedAt time.TimeBalance decimal.Decimalactivebool
}
loc, _:=time.LoadLocation("Europe/Warsaw")
// db.CreateUser("test@example.com")createdAt:=time.Now()
user:=User{
Id: uuid.New(),
Email: "test@example.com",
CreatedAt: createdAt,
Balance: decimal.NewFromFloat(1),
active: true,
}
want:=User{
Email: "test@example.com",
CreatedAt: createdAt.In(loc),
Balance: decimal.RequireFromString("1"),
}
}Running go test on:
| Assert | Testify |
|---|---|
assert.Equal(t, user, want, IgnoreUnexported(), SkipEmptyFields()) | require.Equal(t, user, want) |