its provides value matchers, matcher generator and mock generator.
go get github.com/youta-t/its
Its requires go1.21+.
github.com/youta-t/its package is core package.
Built-in mathcers are here.
For example, its.EqEq matcher is for comparable.
import (
"testing"
"github.com/youta-t/its"
)
func Add(a, b int) int {
return a + b
}
func TestAdd(t *testing.T) {
got := Add(3, 7)
its.EqEq(10). // want is 10
Match(got). // got
OrError(t) // test
}It passes becauase 10 == 3 + 7 is true.
All matchers have example. See them in pkg.go.dev: https://pkg.go.dev/github.com/youta-t/its and doc/getting-started.
If unmatch is fatal, you can do so.
import (
"testing"
"errors"
"github.com/youta-t/its"
)
func Div(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("zero div!")
}
return a + b
}
func TestAdd(t *testing.T) {
_, err := Div(3, 0)
its.Nil[error](). // want is nil.
Match(err). // got
OrFatal(t) // test
}If it does not match, it leave nice message.
import "testing"
import "github.com/youta-t/its"
// ...
func Add(a, b int) int {
return a + b
}
func TestAdd(t *testing.T) {
got := Add(3, 7)
its.EqEq(got).Match(10).OrError(t)
its.EqEq(got).Match(11).OrError(t)
}provides,
--- FAIL: TestAdd (0.00s)
✘ /* got */ 11 == /* want */ 10 --- @.../example_test.go:33:
Error message is tailored for each matchers.
Generally, each messages start with...
✔: passed matcher✘: failed matcher~: failed matcher, but not matter
Mathers of its can be composed. For example,
package example_test
import (
"testing"
"github.com/youta-t/its"
)
func TestBetween(t *testing.T) {
its.All(
its.GreaterThan(3),
its.LesserEq(8),
).Match(7).OrError(t) // pass. 3 < 7 <= 8
its.All(
its.GreaterThan(3),
its.LesserEq(8),
).Match(8).OrError(t) // pass. 3 < 8 <= 8
its.All(
its.GreaterThan(3),
its.LesserEq(8),
).Match(9).OrError(t) // fail! 3 < 9 <= 8
}provides,
--- FAIL: TestBetween (0.00s)
✘ // all: (1 ok / 2 matchers) --- @.../example_test.go:19
✔ /* want */ 3 < /* got */ 9 --- @ .../example_test.go:20
✘ /* want */ 8 > /* got */ 9 --- @ .../example_test.go:21
"A between B" means "greater than A, and lesser than B".
there are also Some (require match at least one), Not (invert match) and None (= Not(Some(...)) + better message).
its has a tool for //go:generate to generate matchers of struct, github.com/youta-t/its/structer.
You can get matchers for structs, type T []E and type T map[K]E (alias of slice/map) in and not in your package.
See structer/README.md for more details.
There are another //go:generate feature to generate mocks of functions and interfaces, github.com/youta-t/its/mocker.
You can mock builders for each type ... interface and type ... func.
And more, there are "scenario" test feature to check injected functions are called in exact order.
See mocker/README.md for more details.
Matcher developmenet kit, itskit, is included.
You can create your matcher from scratch in 50 lines or so. Or, in the simplest case, you need just 10 lines per one matcher.
See doc/how-to-write-my-matcher.md to know how to.