Documentation
¶
Overview ¶
Example (Expectation_IsNil) ¶
var ( value int = 42 ref *int ) // this test will pass Expect(ref).IsNil() // this test will fail ref = &value Expect(ref).IsNil()
Output: expected nil, got 42 [*int]
Example (Expectation_IsNotNil) ¶
var ( value int = 42 ref *int ) // this test will pass ref = &value Expect(ref, "non-nil ref").IsNotNil() // this test will fail ref = nil Expect(ref, "nil ref").IsNotNil()
Output: nil ref: expected not nil
Index ¶
- Variables
- func BeBetween[T cmp.Ordered](v T) ordered.IsBetweenInitializer[T]
- func BeEmpty() *emptiness.Matcher
- func BeEmptyOrNil() *emptiness.Matcher
- func BeFalse() bools.BooleanMatcher
- func BeGreaterThan[T cmp.Ordered](want T) ordered.RelativeMatcher[T]
- func BeLessThan[T cmp.Ordered](want T) ordered.RelativeMatcher[T]
- func BeNil() nilness.Matcher
- func BeOfType[T any]() typecheck.Matcher[T]
- func BeTrue() bools.BooleanMatcher
- func Case[T any](name string, tc T) testcase.Registration[T]
- func Cases[T any](cases []T) testcase.Registration[T]
- func Cleanup(fn func())
- func ContainItem[T any](item T) slices.ContainsItemMatcher[T]
- func ContainItems[T any](items []T) slices.ContainsItemsMatcher[T]
- func ContainMap[K comparable, V any](want map[K]V) maps.ContainsMatcher[K, V]
- func ContainMapEntry[K comparable, V any](key K, value V) maps.ContainsMatcher[K, V]
- func ContainSlice[T any](e []T) slices.ContainsSliceMatcher[T]
- func ContainString(expected string) strings.ContainsMatch
- func Debug[T any](name string, tc T) testcase.Registration[T]
- func DeepEqual[T any](want T) equal.DeepMatcher[T]
- func Equal[T comparable](want T) equal.Matcher[T]
- func EqualBytes[T ~byte](want []T) *bytes.EqualMatcher[T]
- func EqualMap[K comparable, V any](want map[K]V) maps.EqualMatcher[K, V]
- func EqualSlice[T any](e []T) slices.EqualMatcher[T]
- func Error(msg string)
- func Errorf(s string, args ...any)
- func Expect[T any](value T, opts ...any) *expectation[T]
- func ExpectType[T any](got any, opts ...any) (T, bool)
- func ExpectationsWereMet(m Mock, opts ...any)
- func Fail(opts ...any)
- func FailIf(cond bool, opts ...any)
- func FailIfNot(cond bool, opts ...any)
- func FlakyTest(name string, fn func(), opts ...FlakyOption) flakyRunner
- func HaveContextKey[K comparable](k K) *contexts.KeyMatcher[K]
- func HaveContextValue[K comparable, V any](k K, v V) *contexts.ValueMatcher[K, V]
- func HaveLen(n int) *length.Matcher
- func HelperTests(scns ...HelperScenario) helpertestRunner
- func IsParallel() bool
- func KeysOfMap[K comparable, V any](m map[K]V) []K
- func MatchRegEx(regex string) strings.RegExMatch
- func MeetExpectations() *mocks.Matcher
- func NilPanic() panics.Expected
- func Original[T any](v *T) restorable[T]
- func Panic(r ...any) panics.Expected
- func Parallel(t TestingT)
- func ParallelCase[T any](name string, tc T) testcase.Registration[T]
- func ParallelCases[T any](exec TestExecutor[T], cases ...testcase.Registration[T]) testcase.Runner[T]
- func ParallelTest(name string, fn func()) testRunner
- func Record(fn func()) ([]string, []string)
- func Require[T any](value T, opts ...any) *expectation[T]
- func RequireType[T any](got any, opts ...any) T
- func Reset(r ...Resetter)
- func Restore[T any](fn func(restorable[T]))
- func Run(r Runnable)
- func Skip[T any](name string, tc T) testcase.Registration[T]
- func SkipNow(reason string)
- func StopWatch(f func()) time.Duration
- func Test(name string, fn func()) testRunner
- func Testcases[T any](exec TestExecutor[T], cases ...testcase.Registration[T]) testcase.Runner[T]
- func ValuesOfMap[K comparable, V any](m map[K]V) []V
- func With(t TestingT)
- type AnyMatcher
- type FakeResult
- type FlakyOption
- type Helper
- type HelperScenario
- type Matcher
- type Mock
- type MockFn
- func (mock *MockFn[A, R]) ExpectCall() *mockFnCall[A, R]
- func (mock *MockFn[A, R]) ExpectationsWereMet() error
- func (mock *MockFn[A, R]) RecordCall(args ...A) (R, error)
- func (mock *MockFn[A, R]) Reset()
- func (mock *MockFn[A, R]) ResultFor(args A) FakeResult[R]
- func (mock *MockFn[A, R]) WhenCalledWith(args A) *FakeResult[R]
- type R
- type Resetter
- type Runnable
- type TestExecutor
- type TestingT
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidArgument indicates that an argument provided to a function or method is invalid. ErrInvalidArgument = errors.New("invalid argument") // ErrInvalidOperation indicates that an attempted operation is invalid in the current context. ErrInvalidOperation = errors.New("invalid operation") )
general errors
var ( // ErrExpectationsNotMet indicates that the expectations set on a mock or fake // were not met. ErrExpectationsNotMet = errors.New("expectations not met") // ErrExpectedArgs indicates that arguments were expected but not recorded. ErrExpectedArgs = errors.New("arguments were expected but not recorded") // ErrNoResultForArgs indicates that no result was found for the given arguments. ErrNoResultForArgs = errors.New("no result for arguments") // ErrUnexpectedArgs indicates that the arguments recorded did not match those expected. ErrUnexpectedArgs = errors.New("the arguments recorded did not match those expected") // ErrUnexpectedCall indicates that a call was made that was not expected. ErrUnexpectedCall = errors.New("unexpected call") // ErrResultNotUsed indicates that a result was provided but not used. ErrResultNotUsed = errors.New("result not used") )
mock and fake errors
var ( // ErrRecordingFailed indicates that an error occurred while trying to // record output. ErrRecordingFailed = errors.New("recording failed") // ErrRecordingStdout indicates that an error occurred while trying to // record stdout. ErrRecordingStdout = errors.New("error recording stdout") // ErrRecordingStderr indicates that an error occurred while trying to // record stderr. ErrRecordingStderr = errors.New("error recording stderr") // ErrFailedToRedirectLogger indicates that an error occurred while trying // to redirect logger output. ErrFailedToRedirectLogger = errors.New("failed to redirect logger output") // Deprecated: this error is deprecated and will be removed in a future version; // use [ErrFailedToRedirectLogger] instead. ErrRecordingUnableToRedirectLogger = ErrFailedToRedirectLogger )
recording errors
Functions ¶
func BeBetween ¶ added in v0.11.0
func BeBetween[T cmp.Ordered](v T) ordered.IsBetweenInitializer[T]
BeBetween returns a matcher that will fail if the matched value is not between the limits of a defined interval. The type T must be ordered (i.e. it must support the comparison operators <, <=, >, >=).
BeBetween accepts a single value as an argument providing one limit of the interval. The second limit is provided by calling the [And] method on the returned initializer:
Expect(n).To(BeBetween(10).And(20))
By default the matcher compares the matched value to the closed interval defined by the specified values.
Supported Options ¶
The interval can be changed by providing an opt.IntervalClosure option. The default interval is opt.IntervalClosed. Other options are:
- opt.IntervalOpen for an open interval (min < x < max)
- opt.IntervalOpenMin for a half-open interval (min < x <= max)
- opt.IntervalOpenMax for a half-open interval (min <= x < max)
func BeEmpty ¶ added in v0.9.0
BeEmpty returns a matcher that checks if the value is empty.
The returned matcher is an `AnyMatcher` that may only be used with the `Should()` method, or with `To()` where the subject is of formal type any.
NOTE: A nil value is not considered empty and will fail this test. To test for an empty value that may be nil, use BeEmptyOrNil() instead.
i.e. an empty slice will pass this test, but a nil slice will not.
This test may be used to check for empty strings, arrays, slices, channels, maps and any type that implement a Count(), Len() or Length() function returning int, int64, uint, or uint64.
If a value of any other type is tested, the test fails with a message similar to:
emptiness.Matcher: requires a value of type string, array, slice, channel or map,
or a type that implements a Count(), Len(), or Length() function
returning int, int64, uint, or uint64.
Supported Options ¶
opt.FailureReport(func) // a function that returns a custom test
// failure report if the test fails.
opt.OnFailure(string) // a string to output as the failure
// report if the test fails.
func(v T) bool // a function that returns true if the value
// is empty; the value argument must be of
// the same type as the expectation subject.
Example ¶
test.Example()
// these tests all pass:
Expect([]int{}).Should(BeEmpty())
Expect("").Should(BeEmpty())
Expect(map[int]string{}).Should(BeEmpty())
Expect([0]int{}).Should(BeEmpty())
// these tests all fail:
Expect([]int{1}).Should(BeEmpty())
var ch chan int
Expect(ch, "nil channel").Should(BeEmpty())
var ns []int
Expect(ns, "nil slice").Should(BeEmpty())
var nm map[int]struct{}
Expect(nm, "nil map").Should(BeEmpty())
Output: expected: <empty slice> got : [ 1 nil channel: expected: <empty chan> got : <nil> nil slice: expected: <empty slice> got : <nil> nil map: expected: <empty map> got : <nil>
func BeEmptyOrNil ¶ added in v0.9.0
BeEmptyOrNil returns a matcher that checks if a value is empty or nil.
Compatible Methods and Subjects ¶
Expect(any(subject)).To(...) // i.e. where 'subject' is of type `any` Expect(subject).Should(...) // for any 'subject'
This matcher may be used to check for empty strings and arrays as well as empty or nil slices, channels, maps and any type that implements a Count(), Len() or Length() method returning int, int64, uint, or uint64.
If the subject is of any other type is tested, the test fails with a message similar to:
emptiness.Matcher: requires a value of type string, array, slice, channel or map,
or a type that implements a Count(), Len(), or Length() function
returning int, int64, uint, or uint64.
Supported Options ¶
opt.FailureReport(func) // a function that returns a custom test
// failure report if the test fails.
opt.OnFailure(string) // a string to output as the failure
// report if the test fails.
func(v T) bool // a function that returns true if the value
// is empty or nil; the value argument must be of
// the same type as the subject.
Example ¶
test.Example()
// these tests all pass:
Expect([]int{}).Should(BeEmptyOrNil())
Expect("").Should(BeEmptyOrNil())
Expect(map[int]string{}).Should(BeEmptyOrNil())
Expect([0]int{}).Should(BeEmptyOrNil())
var ch chan int
Expect(ch, "nil channel").Should(BeEmptyOrNil())
var ns []int
Expect(ns, "nil slice").Should(BeEmptyOrNil())
var nm map[int]struct{}
Expect(nm, "nil map").Should(BeEmptyOrNil())
// this test will fail:
Expect([]int{1}).Should(BeEmptyOrNil())
Output: expected: <empty slice> got : [ 1
func BeFalse ¶ added in v0.8.0
func BeFalse() bools.BooleanMatcher
BeFalse returns a matcher that will fail if the matched value is not false.
Supported Options ¶
opt.FailureReport(...) // a function returning a custom failure report
// in the event that the test fails
Example ¶
ExampleBeFalse demonstrates the use of the BeFalse matcher, showing how to use the matcher to assert that a boolean value is false and providing an example of the expected default output when the matcher fails.
test.Example() Expect(true).To(BeFalse())
Output: expected false
func BeGreaterThan ¶ added in v0.8.0
func BeGreaterThan[T cmp.Ordered](want T) ordered.RelativeMatcher[T]
BeGreaterThan returns a matcher that will fail if the matched value is not greater than the expected value. The type T must be ordered (i.e. it must support the comparison operators <, <=, >, >=).
By default the matcher uses the > operator to compare the values. This can be overridden by providing a custom comparison function as an option. The function must take two arguments of type T and return a boolean indicating whether the first argument is greater than the second argument.
To compare values using the <= operator, call the [OrEqual] modifier method on the returned matcher:
Expect(n).To(BeGreaterThan(10).OrEqual())
Supported Options ¶
func(T, T) bool // a custom comparison function to compare values
// (overriding the use of the > operator)
opt.QuotedStrings(bool) // determines whether string values are quoted
// in test failure report (quoted by default);
// the option has no effect if the value is not
// a string type
opt.FailureReport(...) // a function returning a custom failure report
// in the event that the test fails
opt.OnFailure(string) // a string to output as the failure
// report if the test fails
func BeLessThan ¶ added in v0.8.0
func BeLessThan[T cmp.Ordered](want T) ordered.RelativeMatcher[T]
BeLessThan returns a matcher that will fail if the matched value is not less than the expected value. The type T must be ordered (i.e. it must support the comparison operators <, <=, >, >=).
By default the matcher uses the < operator to compare the values. This can be overridden by providing a custom comparison function as an option. The function must take two arguments of type T and return a boolean indicating whether the first argument is less than the second argument.
To compare values using the <= operator, call the [OrEqual] modifier method on the returned matcher:
Expect(n).To(BeLessThan(10).OrEqual())
Supported Options ¶
func(T, T) bool // a custom comparison function to compare values
// (overriding the use of the < operator)
opt.QuotedStrings(bool) // determines whether string values are quoted
// in test failure report (quoted by default);
// the option has no effect if the value is not
// a string type
opt.FailureReport(...) // a function returning a custom failure report
// in the event that the test fails
opt.OnFailure(string) // a string to output as the failure
// report if the test fails
func BeNil ¶ added in v0.9.0
BeNil returns a matcher that checks if the value is nil.
The returned matcher is an `AnyMatcher` that may only be used with the `Should()` method, or with `To()` where the subject is of formal type any.
If used in a To() or Should() test with a subject that is not nilable, the test fails with a message similar to:
test.BeNil: values of type '<type>' are not nilable
If used with ToNo() or ShouldNot() a non-nilable subject will pass the test.
Supported Options ¶
opt.QuotedStrings(bool) // determines whether any non-nil string
// values are quoted in any test failure
// report. The default is false (string
// values are quoted).
//
// If the value is not a string type this
// option has no effect.
opt.FailureReport(func) // a function that returns a custom test
// failure report if the test fails.
opt.OnFailure(string) // a string to output as the failure
// report if the test fails.
func BeOfType ¶ added in v0.12.0
BeOfType returns a matcher that checks if the value is of the expected type.
To perform further tests on a value that passes this check using a strongly typed value of the expected type, use expect.Type or require.Type instead.
Example ¶
test.Example() var i int = 42 Expect(i).Should(BeOfType[int]()) // passes Expect(i).ShouldNot(BeOfType[string]()) // passes Expect(i).Should(BeOfType[bool]()) // fails
Output: expected type: bool got : int
func BeTrue ¶ added in v0.8.0
func BeTrue() bools.BooleanMatcher
BeTrue returns a matcher that will fail if the matched value is not true.
Supported Options ¶
opt.FailureReport(...) // a function returning a custom failure report
// in the event that the test fails
Example ¶
ExampleBeTrue demonstrates the use of the BeTrue matcher, showing how to use the matcher to assert that a boolean value is true and providing an example of the expected default output when the matcher fails.
test.Example() Expect(false).To(BeTrue())
Output: expected true
func Case ¶ added in v0.10.0
func Case[T any](name string, tc T) testcase.Registration[T]
Case adds a test case to the runner. The name is used to identify the test case in the test output and any Before/Each scaffolding functions. The tc provides the data for the test case.
If the name is an empty or whitespace string, a name will be determined as follows:
- if the test case data is a struct (or pointer to a struct) and has a string field named "Scenario", "scenario", "Name", or "name", with a non-empty or whitespace value, that will be used as the name. Otherwise a default name is derived in the format "testcase-NNN" where NNN is the 1-based index of the test case in the list of test cases.
If the test case data has a bool field named debug/Debug that is set true, the test case will be marked as a debug test case. When 1 or more debug test cases are detected only those cases will be executed.
If the test case data has a bool field named skip/Skip that is set true, the test case will be skipped, even if it is also marked as a debug test case.
func Cases ¶ added in v0.10.0
func Cases[T any](cases []T) testcase.Registration[T]
Cases registers a slice of test cases with the runner. This is a convenience function that is equivalent to calling Case() for each test case in the slice with an empty name.
If the test case type T is a struct (or pointer to a struct) and has a string field named "Scenario", "scenario", "Name", or "name", with a value that is not empty and not whitespace, that will be used as the name. Otherwise a default name is derived in the format "testcase-NNN" where NNN is the 1-based index of the test case in the list of test cases.
func Cleanup ¶ added in v0.8.0
func Cleanup(fn func())
Cleanup adds a function to the list of functions to be called when the test finishes. The function will be called in reverse order of registration.
If a nil function is passed, it is ignored.
This is a wrapper around the *testing.T.Cleanup() method with the addition of accepting (but ignoring) a nil function.
func ContainItem ¶ added in v0.8.0
func ContainItem[T any](item T) slices.ContainsItemMatcher[T]
ContainItem returns a matcher for slices of comparable types that is satisfied if the slice contains at least one item that is equal to the expected item.
The Matcher supports the following options:
- func(T, T) bool
- func(any, any) bool
The options allow a test to supply a custom comparison function to be used to compare the expected item with the items in the slice. The comparison function must return true if the two arguments are equal.
If both types of functions are provided the matcher will panic with ErrInvalidOption.
The default comparison function is reflect.DeepEqual.
Example ¶
test.Example()
sut := []string{"a", "b"}
// these tests will pass
Expect(sut).To(ContainItem("a"))
Expect(sut).To(ContainItem("A"), opt.CaseInsensitive)
// this test will fail
Expect(sut).To(ContainItem("c"))
Output: expected []string containing: "c" got: [ "a" [ "b"
func ContainItems ¶ added in v0.8.0
func ContainItems[T any](items []T) slices.ContainsItemsMatcher[T]
ContainItems returns a matcher for slices of comparable types that is satisfied if the slice contains all of the items in the expected slice. The items in the expected slice may occur in any order in the got slice and need not be contiguous.
The the following options are supported:
- func(T, T) bool
- func(any, any) bool
The options allow a test to supply a custom comparison function to be used to compare the expected item with the items in the slice. The comparison function must return true if the two arguments are equal.
If both types of functions are provided the matcher will panic with ErrInvalidOption.
The default comparison function is reflect.DeepEqual.
func ContainMap ¶ added in v0.8.0
func ContainMap[K comparable, V any](want map[K]V) maps.ContainsMatcher[K, V]
ContainMap returns a matcher that will match if a map contains an expected compatible map. The matcher will pass if the map contains all of the key-value pairs in the expected map.
Values are compared as follows, in order of preference:
- V.Equal(V) when V implements the Equal method
- a comparison function option of the form func(V, V) bool
- a comparison function option of the form func(any, any) bool
- reflect.DeepEqual
Supported Options ¶
func(V, V) bool // a custom comparison function to compare
// map values.
func(any, any) bool // a custom comparison function to compare
// map values.
opt.CaseSensitive(bool) // used to indicate whether the comparison of
// string values should be case-sensitive
// (default is true).
//
// This option is also applied to values that
// are slices or arrays of a string type.
//
// The option does NOT apply to string fields
// in structs or values that are maps.
//
// NOTE: string keys are ALWAYS case-sensitive.
opt.ExactOrder(bool) // used to indicate whether the order of
// elements in values that are slices or arrays
// is significant (default is true).
//
// NOTE: order is never significant for map keys.
opt.QuotedStrings(bool) // determines whether string keys or values are
// quoted in any test failure report. Default
// is true.
//
// This option has no effect for keys or values
// that are not strings.
opt.FailureReport(func) // a function that returns a custom test
// failure report if the test fails.
opt.OnFailure(string) // a string to output as the failure
// report if the test fails.
func ContainMapEntry ¶ added in v0.8.0
func ContainMapEntry[K comparable, V any](key K, value V) maps.ContainsMatcher[K, V]
ContainMapEntry is a convenience function to test that a map contains a specific key-value pair.
i.e. the following are equivalent:
Expect(someMap).To(ContainMapEntry(key, value))
Expect(someMap).To(ContainMap(map[K]V{key: value}))
Values are compared as follows, in order of preference:
- V.Equal(V) when V implements the Equal method
- a comparison function option of the form func(V, V) bool
- a comparison function option of the form func(any, any) bool
- reflect.DeepEqual
Supported Options ¶
// supported options are the same as for ContainMap()
func ContainSlice ¶ added in v0.8.0
func ContainSlice[T any](e []T) slices.ContainsSliceMatcher[T]
ContainSlice returns a matcher for a slice that is satisfied if the slice contains items that correspond to the items in a given other slice.
Comparison of items is performed using reflect.DeepEqual by default but may be overridden by supplying one of:
func(T, T) bool func(any, any) bool
func ContainString ¶ added in v0.8.0
func ContainString(expected string) strings.ContainsMatch
func Debug ¶ added in v0.10.0
func Debug[T any](name string, tc T) testcase.Registration[T]
Debug adds a test case to the runner and marks it as a debug case.
When running test cases, if any cases are marked as debug only those cases will be run. This is useful for debugging specific test cases without running the entire suite.
Adding a test case using Debug() overrides any debug/skip fields that may be present in the test case data itself.
When any debug test cases are run, the test case runner itself will fail the test with a warning that only debug cases were evaluated. This is intended to ensure that Debug() cases are not accidentally left in the test suite.
func DeepEqual ¶ added in v0.3.0
func DeepEqual[T any](want T) equal.DeepMatcher[T]
DeepEqual returns a matcher that checks if a value of type T is equal to some expected value of type T.
Equality is always evaluated using reflect.DeepEqual. i.e. the matcher does not support the use of a custom comparison function and will not use any Equal(T) method implemented by type T.
To use a custom comparison function or a T.Equal(T) method, use the Equal() matcher.
Supported Options ¶
opt.QuotedString(bool) // determines whether string values in failure reports
// are quoted (default is true); the option has no
// effect on values that are not strings
//
// this option applies only to values being directly
// compared; it is not applied to string fields of
// struct types, for example
opt.FailureReport(func) // a function returning a custom failure report
// when the values are not equal
Example ¶
test.Example()
Expect([]byte{1, 2, 3}).To(DeepEqual([]byte{1, 2, 4}))
Expect([]uint8{1, 1, 2, 3, 5}).To(DeepEqual([]uint8{1, 2, 4, 8, 16}))
// this will not compile because the types are not the same:
// Expect([]uint8{1, 1, 2, 3, 5}).To(DeepEqual([]int{1,1,2,3,5}))
Output: expected: []uint8 (len,cap=3) [1, 2, 4] got : []uint8 (len,cap=3) [1, 2, 3] expected: []uint8 (len,cap=5) [1, 2, 4, 8, 16] got : []uint8 (len,cap=5) [1, 1, 2, 3, 5]
func Equal ¶
func Equal[T comparable](want T) equal.Matcher[T]
Equal returns a matcher that checks if a value of type T is equal to some expected value of type T. The type T must be comparable.
Equality is determined using ONE of the following, in order of preference:
- any comparison function provided as an option
- a T.Equal(T) bool method, if it exists
- the == operator
If specified, a custom comparison function must take two arguments of type T, returning a boolean indicating whether the values are considered equal.
Supported Options ¶
func(T, T) bool // a function to compare the values
// (overriding the use of the == operator or
// T.Equal(T) method, if it exists)
opt.QuotedString(bool) // determines whether string values in failure reports
// are quoted (default is true); the option has no
// effect on values that are not strings
//
// this option applies only to values being directly
// compared; it is not applied to string fields of
// struct types, for example
opt.FailureReport(func) // a function returning a custom failure report
// when the values are not equal
Example ¶
test.Example()
Expect(1).To(Equal(2))
Expect("the hobbit").To(Equal("the lord of the rings"))
// this will not compile because the types are not the same:
// Expect(42).To(Equal("the answer"))
// this will not compile because the types are not comparable:
// Expect([]int{1, 2, 3}).To(Equal([]int{1, 2, 3}))
//
// instead, use:
// Expect(..).To(DeepEqual(..))
//
// or, for slices:
// Expect(..).To(EqualSlice(..))
Output: expected 2, got 1 expected: "the lord of the rings" got : "the hobbit"
func EqualBytes ¶ added in v0.8.0
func EqualBytes[T ~byte](want []T) *bytes.EqualMatcher[T]
EqualBytes returns a matcher that checks if a byte slice is equal to an expected byte slice.
The type T must be byte or a type that is assignable to byte. The matcher uses reflect.DeepEqual to compare the slices; this enables the matcher to be used with slices of custom byte types.
The matcher reports differences in human-readable format.
The failure report identifies the offsets of all differences and shows a portion of the expected and actual byte slices to highlight the first such difference. See the example for a demonstration.
Supported Options ¶
This is a highly specialised matcher; the only supported option is a custom failure report function:
opt.FailureReport(func) // a function returning a custom failure report
// in the event that the slices are not equal
Example ¶
ExampleEqualBytes demonstrates the use of the EqualBytes matcher, showing how to use the matcher to assert that two byte slices are equal and providing an example of the expected default output when the matcher fails.
test.Example()
a := []byte{0x01, 0x02, 0x03}
b := []byte{0x01, 0x03, 0x02}
Expect(a).To(EqualBytes(b))
Output: bytes not equal: differences at: [1, 2] expected: 01 03 02 | ** ** got : 01 02 03
func EqualMap ¶ added in v0.8.0
func EqualMap[K comparable, V any](want map[K]V) maps.EqualMatcher[K, V]
EqualMap returns a matcher that will match if the wanted map is equal to the actual map.
To be equal, the maps must have the same number of keys and each key must have a value that is equal to the value of the same key in both maps.
The order of the keys in the maps is not significant.
Values are compared as follows, in order of preference:
- V.Equal(V) when V implements the Equal method
- a comparison function option of the form func(V, V) bool
- a comparison function option of the form func(any, any) bool
- reflect.DeepEqual
This test is a convenience for separately testing length and content of two maps. i.e. the following are equivalent:
Expect(got).To(EqualMap(want))
and
Expect(len(got)).To(Equal(len(want))) Expect(got).To(ContainMap(want))
However, although the above tests are equivalent in terms of test outcome, the test failure report for the EqualMap() test is more informative than the two tests combined, expressing the intent that the maps be equal.
Supported Options ¶
// supported options are the same as for ContainMap()
Example ¶
test.Example()
sut := map[string]int{
"ford": 42,
"arthur": 23,
}
// this test will pass
Expect(sut).To(EqualMap(map[string]int{
"ford": 42,
"arthur": 23,
}))
// this test will fail
sut = map[string]int{"marvin": 99}
Expect(sut).To(EqualMap(map[string]int{"trillian": 24}))
Output: expected map[string]int: ( "trillian" => 24 got: ( "marvin" => 99
func EqualSlice ¶ added in v0.8.0
func EqualSlice[T any](e []T) slices.EqualMatcher[T]
EqualSlice compares the actual slice with an expected slice and fails the test if they are not equal.
By default, the order of elements in each slice is significant. That is, the nth each slice must be equal. If the order of elements is not significant, use the ExactOrder option to specify that the order of elements is not significant, e.g.:
got := []int{1, 2, 3}
expected := []int{3, 2, 1}
Expect(got).To(EqualSlice(expected)) // will fail
Expect(got).To(EqualSlice(expected), opt.ExactOrder(false)) // will pass
func Error ¶ added in v0.3.0
func Error(msg string)
Error explicitly and unconditionally fails the current test with the given message.
This should not be confused with the `test.Error` function used to report an error condition in a test helper (from the blugnu/test/test package).
func Errorf ¶ added in v0.10.0
Errorf explicitly and unconditionally fails the current test with the formatted message.
This should not be confused with the `test.Error` function used to report an error condition in a test helper (from the blugnu/test/test package).
func Expect ¶ added in v0.8.0
Expect creates an expectation for the given value. The value may be of any type.
Supported Options ¶
string // a name for the expectation; the name is used in
// the failure message if the expectation fails.
opt.Name(string) // a name for the expectation; this is an alternate
// way to supply the name, equivalent to passing a
// string directly.
opt.Namef(s, args...) // a formatted name for the expectation; this is an
// alternate way to supply the name, equivalent to
// passing the result of fmt.Sprintf() directly.
opt.IsRequired(bool) // if true, the expectation is required to pass;
// no further expectations in the current test will be
// evaluated if the expectation fails.
opt.Required() // equivalent to opt.IsRequired(true)
func ExpectType ¶ added in v0.8.0
ExpectType tests that a value is of an expected type. If the test passes, the value is returned as that type, with true. If the test fails the zero value of the specified type is returned, with false.
Example ¶
test.Example()
// ExpectType returns the value as the expected type and true if the
// value is of that type
var got any = 1 / 2.0
result, ok := ExpectType[float64](got)
fmt.Printf("ok is %v\n", ok)
fmt.Printf("result: type is: %T\n", result)
fmt.Printf("result: value is: %v\n", result)
// ExpectType returns the zero value of the expected type and false if the
// value is not of that type (the return values can be ignored if the
// test is only concerned with checking the type)
got = "1 / 2.0"
ExpectType[float64](got)
Output: ok is true result: type is: float64 result: value is: 0.5 expected: float64 got : string
func ExpectationsWereMet ¶ added in v0.4.0
ExpectationsWereMet is a convenience function for testing and resetting expectations of a mock that implements the test.Mock interface:
type Mock interface {
ExpectationsWereMet() error
Reset()
}
The mock is guaranteed to be reset whether expecations were met or not.
If a test is not concerned with expectations being met and is using a mock simply to provide complex mocked responses, the mock can be reset without checking expectations by passing the mock to the Reset() helper.
Supported Options ¶
string // a name for the expectation; the name is used in
// the failure message if the expectation fails.
// # Example
func TestSomething(t *testing.T) {
With(t)
// ARRANGE
mock1 := NewMock()
mock2 := NewMock()
mock3 := NewMock()
defer Reset(mock1, mock2, mock3)
// .. configure expectations on mocks
// ACT
// .. call the code under test
// ASSERT
// .. additional assertions prior to the deferred testing
test.ExpectationsWereMet(mock1, "mock 1")
test.ExpectationsWereMet(mock2, "mock 2")
test.ExpectationsWereMet(mock3, "mock 3")
}
func Fail ¶ added in v0.13.0
func Fail(opts ...any)
Fail explicitly and unconditionally fails the current test with the given options.
If the supplied options do not contain a string, []string or opt.FailReporter, the test is failed with a "test failed" message.
func FailIf ¶ added in v0.13.0
FailIf fails the current test with the given options only if a specified condition is true.
If the supplied options do not contain a string, []string or opt.FailReporter, the test is failed with a "test failed" message.
func FailIfNot ¶ added in v0.13.0
FailIfNot fails the current test with the given options only if a specified condition is not true.
If the supplied options do not contain a string, []string or opt.FailReporter, the test is failed with a "test failed" message.
func FlakyTest ¶ added in v0.11.0
func FlakyTest(name string, fn func(), opts ...FlakyOption) flakyRunner
FlakyTest creates a runner for a test that may fail intermittently. The test will be retried up to a specified number of MaxAttempts or until MaxDuration has passed (whichever occurs first).
If the test passes, no failure report is produced; reports from any failed attempts are discarded.
If the test does not pass on any attempt, a report is generated that includes the details of all failed attempts.
By default, the test will be attempted up to 3 times for up to 1 second.
You can configure the maximum number of attempts and the maximum duration using the MaxAttempts and MaxDuration options, respectively. Setting these options to 0 (zero) disables each limit. Setting both options to 0 (zero) allows the test to run indefinitely until it passes, the 'go test' timeout is reached, or the process is terminated.
Example usage:
// run a test for a maximum of 5 attempts over a 200 millisecond period
Run(FlakyTest("test that fails intermittently", func() {
// .. test code ..
}, MaxDuration(200*time.Millisecond), MaxAttempts(5)))
func HaveContextKey ¶ added in v0.8.0
func HaveContextKey[K comparable](k K) *contexts.KeyMatcher[K]
HaveContextKey returns a matcher that checks if a context contains a specific key. The key type must be comparable. The matcher will fail if the key is not present in the context.
Supported Options ¶
opt.QuotedStrings(bool) // determines whether string values are quoted in test
// failure report (quoted by default); the option has
// has no effect if the key is not a string type
opt.FailureReport(func) // a function returning a custom failure report
// in the event that the test fails
Example ¶
ExampleHaveContextKey demonstrates the use of the HaveContextKey matcher, showing how to use the matcher to assert that a context contains a specific key and providing an example of the expected default output when the matcher fails.
test.Example() type key int ctx := context.WithValue(context.Background(), key(57), "varieties") // these tests will pass Expect(ctx).To(HaveContextKey(key(57))) Expect(ctx).ToNot(HaveContextKey(key(58))) // this test will fail Expect(ctx).To(HaveContextKey(key(58)))
Output: expected key: test.key(58) key not present in context
func HaveContextValue ¶ added in v0.8.0
func HaveContextValue[K comparable, V any](k K, v V) *contexts.ValueMatcher[K, V]
HaveContextValue returns a matcher that checks if a context contains a specific key-value pair.
The key type (K) must be comparable. The matcher will fail if the key is not present in the context or if the value does not match the expected value. The value type (V) can be any type.
The matcher uses reflect.DeepEqual to compare the expected value with any value in the context for the specified key; this may be overridden by supplying a custom comparison function in the options.
Supported Options ¶
func(V, V) bool // a custom comparison function to compare values
// (overriding the use of reflect.DeepEqual)
opt.QuotedStrings(bool) // determines whether string keys or values are quoted
// in the test failure report (quoted by default);
// the option has no effect for keys or values that
// are not string type
opt.FailureReport(func) // a function returning a custom failure report
// in the event that the test fails
Example ¶
ExampleHaveContextValue demonstrates the use of the HaveContextValue matcher, showing how to use the matcher to assert that a context contains a specific key with a specific value and providing an example of the expected default output when the matcher fails.
test.Example() type key int ctx := context.WithValue(context.Background(), key(57), "varieties") // these tests will pass Expect(ctx).To(HaveContextValue(key(57), "varieties")) Expect(ctx).ToNot(HaveContextValue(key(56), "varieties")) Expect(ctx).ToNot(HaveContextValue(key(57), "flavours")) // this test will fail Expect(ctx).To(HaveContextValue(key(57), "flavours"))
Output: context value: test.key(57) expected: "flavours" got : "varieties"
func HaveLen ¶ added in v0.10.0
HaveLen returns a matcher that checks if the value has len() equal to n.
The returned matcher is an AnyMatcher that must be used with [expectation.Should] or [expectation.ShouldNot] expectations. The matcher supports values of any type that is compatible with the built-in len() function. That is:
- array
- channel
- map
- slice
- string
A nil value of any of these types is considered to have a length of 0.
If the value is of any other type, the test fails as invalid, with a message similar to:
`length.Matcher: requires a value that is a string, slice, channel, or map: got <type>`
Example ¶
test.Example()
// these tests all pass:
Expect([]int{}).Should(HaveLen(0))
Expect(map[int]string{}).Should(HaveLen(0))
Expect("").Should(HaveLen(0))
Expect([0]int{}).Should(HaveLen(0))
var ch chan int
Expect(ch, "nil channel").Should(HaveLen(0))
var ns []int
Expect(ns, "nil slice").Should(HaveLen(0))
var nm map[int]struct{}
Expect(nm, "nil map").Should(HaveLen(0))
// these tests all fail:
Expect([]int{1, 2, 3}, "slice").Should(HaveLen(2))
Expect(map[int]struct{}{1: {}, 2: {}, 3: {}}, "map").Should(HaveLen(2))
Expect("abc", "string").Should(HaveLen(2))
Output: slice: expected: len() == 2 got : len() == 3 map: expected: len() == 2 got : len() == 3 string: expected: len() == 2 got : len() == 3
func HelperTests ¶ added in v0.10.0
func HelperTests(scns ...HelperScenario) helpertestRunner
func IsParallel ¶ added in v0.8.0
func IsParallel() bool
IsParallel returns true if the current test is running in parallel or is a sub-test of a parallel test.
func KeysOfMap ¶ added in v0.8.0
func KeysOfMap[K comparable, V any](m map[K]V) []K
KeysOfMap returns the keys of a map as a slice, provided to enable map keys to be tests using slice matchers, written expressively as:
Expect(KeysOfMap(someMap)).To(ContainItem(expectedKey))
The order of the keys in the returned slice is not guaranteed.
func MatchRegEx ¶ added in v0.8.0
func MatchRegEx(regex string) strings.RegExMatch
func MeetExpectations ¶ added in v0.10.0
MeetExpectations is a matcher that checks whether the expectations of a mock were met. It is used in conjunction with the Expect() function to assert
func NilPanic ¶ added in v0.8.0
NilPanic returns an expectation that a panic will occur that recovers a *runtime.PanicNilError.
see: https://go.dev/blog/compat#expanded-godebug-support-in-go-121
For more information, refer to the # The Panic(nil) Special Case described in the Panic function documentation.
func Original ¶ added in v0.9.0
func Original[T any](v *T) restorable[T]
Original is used to create an override for a variable of type T.
The argument v is a pointer to the variable that will be overridden. The function returns a value providing a ReplacedBy method, which can be used to replace the original value with a new one.
func Panic ¶ added in v0.2.0
Panic returns an expectation subject that can be used to test whether a panic has occurred, optionally identifying a value that should match the value recovered from the expected panic.
NOTE: At most ONE panic test should be expected per function. In addition, extreme care should be exercised when combining panic tests with other deferred recover() calls as these will also interfere with a panic test (or vice versa).
Usage ¶
If called with no arguments, any panic will satisfy the expectation, regardless of the value recovered.
If called with a single argument, it will expect to recover a panic that recovers that value (unless the argument is nil; see The Panic(nil) Special Case, below)
If called with > 1 argument, the test will be failed as invalid.
The Panic(nil) Special Case ¶
Panic(nil) is a special case that is equivalent to "no panic expected". This is motivated by table-driven tests to avoid having to write conditional code to handle test cases where a panic is expected vs those where not.
Treating Panic(nil) as "no panic expected" allows you to write:
defer Expect(Panic(testcase.expectedPanic)).DidOccur()
When testcase.expectedPanic is nil, this is equivalent to:
defer Expect(Panic()).DidNotOccur()
Should you need to test for an actual panic(nil), use:
defer Expect(NilPanic()).DidOccur()
Or, in a table-driven test, specify an expected recovery value of &runtime.PanicNilError{}.
Example ¶
test.Example()
// panic tests must be deferred so that the panic can be recovered;
//
// a stack trace is included by default but is disabled here to
// avoid breaking the example output
defer Expect(Panic("some string")).DidOccur(opt.NoStackTrace())
// cause a panic; note that the value is different to the value
// expected to be recovered (established above), so the test will fail
panic("some other string")
Output: unexpected panic: expected : "some string" recovered: "some other string"
func Parallel ¶ added in v0.8.0
func Parallel(t TestingT)
Parallel establishes a new test frame scheduled for parallel execution. It is intended to be used as an alternative to With(t) for a test that is intended to run entirely in parallel.
i.e. use:
func TestSomething(t *testing.T) {
Parallel(t)
// ... test code here ...
}
instead of:
func TestSomething(t *testing.T) {
With(t)
Run(ParallelTest("something", func() {
// ... test code here ...
}))
}
Parallel must not be called from a test that is already parallel or with a nil argument; in both cases the test will be failed as invalid.
func ParallelCase ¶ added in v0.10.0
func ParallelCase[T any](name string, tc T) testcase.Registration[T]
ParallelCase adds a test case to the runner for parallel execution.
Aside from the parallel execution of the test case subtests, this function is otherwise identical to Case().
func ParallelCases ¶ added in v0.10.0
func ParallelCases[T any](exec TestExecutor[T], cases ...testcase.Registration[T]) testcase.Runner[T]
ParallelCases creates a Runner to run a set of test cases in parallel.
Aside from the parallel execution of the test cases, this function is otherwise identical to Testcases().
func ParallelTest ¶ added in v0.10.0
func ParallelTest(name string, fn func()) testRunner
ParallelTest creates a test runner to run a function as a subtest with the provided name, running it in parallel.
If the current test is already parallel, this function will fail the test as invalid since it is not allowed to nest parallel tests.
func Record ¶ added in v0.8.0
Record captures the stdout and stderr output resulting from the execution of some function.
In the unlikely event that the mechanism fails, the function will panic to avoid returning misleading results or require error handling.
Example ¶
// remove date and time from log output otherwise this
// example will fail because the date and time will be
// different each time it is run!
log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime))
// capture the output of a function that explicitly writes
// to stdout, stderr and emits logs (which also go to stderr,
// by default)
stdout, stderr := Record(func() {
fmt.Println("to stdout")
fmt.Fprintln(os.Stderr, "to stderr")
log.Println("to log")
})
// write what was captured to stdout (for the Example to test)
// (in a test, you would use Expect() to test the output)
fmt.Println("captured stdout:")
for i, s := range stdout {
fmt.Printf(" %d: %s\n", i+1, s)
}
fmt.Println("captured stderr:")
for i, s := range stderr {
fmt.Printf(" %d: %s\n", i+1, s)
}
Output: captured stdout: 1: to stdout captured stderr: 1: to stderr 2: to log
func Require ¶ added in v0.9.0
Require creates an expectation for the given value which is required to pass. If the expectation is not met, execution continues with the *next* test (if any); no further expectations in the current test will be evaluated.
This is a convenience function that is equivalent to passing the opt.Required() or opt.IsRequired(true) option to a matcher invoked using Expect(), i.e. the following are equivalent:
Expect(value).To(Equal(expected), opt.IsRequired(true)) Expect(value).To(Equal(expected), opt.Required()) Require(value).To(Equal(expected))
Supported Options ¶
string // a name for the expectation; the name is used in
// the failure message if the expectation fails.
opt.Name(string) // a name for the expectation; this is an alternate
// way to supply the name, equivalent to passing a
// string directly.
opt.Namef(s, args...) // a formatted name for the expectation; this is an
// alternate way to supply the name, equivalent to
// passing the result of fmt.Sprintf() directly.
Example ¶
test.Example()
// this test will fail
Require(true).To(Equal(false))
// this will not be executed because the previous expectation was
// required to pass and did not
Expect("apples").To(Equal("oranges"))
Output: expected false, got true
func RequireType ¶ added in v0.9.1
RequireType tests that a value is of an expected type. If the test passes, the value is returned as that type otherwise the test fails immediately without evaluating any further expectations.
func Reset ¶ added in v0.4.0
func Reset(r ...Resetter)
Reset calls the Reset method on each Resetter in the list. A Resetter is any type that implements the Resetter interface:
type Resetter interface {
Reset()
}
Reset is a convenience function for resetting multiple Resetters, such as fakes and mocks.
Example ¶
func TestSomething(t *testing.T) {
// ARRANGE
fake := NewFake()
mock := NewMock()
defer test.Reset(fake, mock)
// .. set expectations on mock
// ACT
// .. call the code under test
// ASSERT
// .. assertions additional to testing mock expectations (if any)
test.MockExpectations(t, mock)
}
func Restore ¶ added in v0.9.0
func Restore[T any](fn func(restorable[T]))
Restore is used to restore the original value of a variable after it has been temporarily changed for a test using the Original function and its ReplacedBy method.
It should be called in a defer statement to ensure that the original value is restored even if the test panics or fails.
Example ¶
ExampleRestore demonstrates how to use Restore to temporarily replace a variable with a new value for the duration of a test
The example simulates a naive approach to mocking the time.Now function and demonstrates that Restore can be used to temporarily replace variables in a test, including variables that are function references.
To ensure predictable output for the example, instead of using the real time.Now function, we define a variable `now` that returns a fixed time value. This allows us to control the output of the example without relying on the current time, which would vary depending on when the example is run.
This is not a robust mechanism for mocking time.Now, but it serves as an illustration. For a more robust approach to mocking time, consider using a package like github.com/blugnu/time, or similar.
// establish "now" as a function that returns the release date of Go 1.0
// as the "current time".
var now = func() time.Time {
return time.Date(2012, 3, 28, 0, 0, 0, 0, time.UTC)
}
// simulate a sub-test where the "current time" is temporarily
// replaced with a fixed time value.
func() {
var fakeTime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
defer Restore(Original(&now).ReplacedBy(func() time.Time { return fakeTime }))
fmt.Println("now() returns: ", now())
}()
fmt.Println("now() returns: ", now())
Output: now() returns: 2020-01-01 00:00:00 +0000 UTC now() returns: 2012-03-28 00:00:00 +0000 UTC
func Run ¶ added in v0.8.0
func Run(r Runnable)
Run executes the provided Runnable in the current test frame.
It must be called from a Test..(*testing.T) func; it is not supported in Example..() funcs.
func Skip ¶ added in v0.10.0
func Skip[T any](name string, tc T) testcase.Registration[T]
Skip adds a test case to the runner and marks it to be skipped.
Adding a test case using Skip() overrides any skip/debug fields that may be present in the test case data itself.
func SkipNow ¶ added in v0.12.0
func SkipNow(reason string)
SkipNow is a function that is used to skip the current test immediately. It is a wrapper around the SkipNow method of the current test frame.
If the current testframe is a *testing.T (the usual case), the supplied reason for skipping the test is logged. Otherwise, the reason is required for documentation purposes only.
func StopWatch ¶ added in v0.10.0
StopWatch executes the provided function and returns the duration it took to execute.
func Test ¶ added in v0.8.0
func Test(name string, fn func()) testRunner
Test creates a named test runner that can be used to run a test function as a subtest in the current test frame. The name is used as the subtest name, and the function is the test code to be executed.
func Testcases ¶ added in v0.10.0
func Testcases[T any](exec TestExecutor[T], cases ...testcase.Registration[T]) testcase.Runner[T]
Testcases creates a Runner that can be used to run a set of test cases; each test case is performed in its own subtest using a test executor function that is provided as the first argument.
Test Executors ¶
For tests where the test executor is consistent for all test cases, the ForEach() function provides a single test executor function that requires only the test case itself.
If test execution varies for some test cases, the For() function instead provides a test executor that will be called with the name of each test case in addition to the test case itself. The test executor function can then use the test case name to perform any test case specifica variations as required.
Test Cases ¶
Test cases may be specified in two different ways:
by calling the Case(), ParallelCase, Debug() or Skip() fluent methods on the returned Runner; these functions require a name for each case;
as a variadic list of test cases following the test executor; these test cases are expected to be simple values or structs. If a struct type is used that has a name/Name/scenario/Scenario string field, that field will be used as the name for the test case. Otherwise a default name will be generated in the format "testcase-NNN" where NNN is the 1-based index of the test case in the list.
The first form is recommended for cases where the name/scenario of each test case is significant, whether for varying test execution or simply in identifying a failed test case.
The second form is useful for simple test cases where the test executor is the same for all test cases and the index-based identity for each test case is sufficient.
func ValuesOfMap ¶ added in v0.8.0
func ValuesOfMap[K comparable, V any](m map[K]V) []V
ValuesOfMap returns the values of a map as a slice, provided to enable map values to be tests using slice matchers, written expressively as:
Expect(ValuesOfMap(someMap)).To(ContainItem(expectedValue))
The order of the values in the returned slice is not guaranteed.
func With ¶ added in v0.8.0
func With(t TestingT)
With pushes the given TestingT onto the test frame stack; if the TestingT is not nil it will be popped from the stack when the test has completed.
This is used to set the current test frame for the test package, typically called as the first line of a Test...() function:
func TestSomething(t *testing.T) {
With(t)
// ... rest of the test code ...
}
If `blugnu/test` functions are used to run subtests etc, no further calls to With() are required in a test function; the test frame will be automatically managed by the test package.
If a new test frame is explicitly created, e.g. by calling t.Run(string, func(t *testing.T)), then With(t) must be called to push the new test frame onto the stack. Again, this will be automatically popped from the stack when the new test frame completes:
func TestSomething(t *testing.T) {
With(t)
// when using test package functions to run subtests you do not
// need to call With() again
Run(Test("subtest", func() {
// ... rest of the subtest code ...
})
// but With() must be called if a new test frame is explicitly created
t.Run("subtest", func(t *testing.T) {
With(t)
// ... rest of the subtest code ...
})
// ... rest of the test code ...
}
To simultaneously push a test frame and mark it for parallel execution, you can use the Parallel() function:
func TestSomething(t *testing.T) {
Parallel(t)
// ... rest of the test code ...
}
Types ¶
type AnyMatcher ¶ added in v0.10.0
AnyMatcher is the interface implemented by matchers that can test any type of value. It is used to apply matchers to expectations that are not type-specific.
It is preferable to use the Matcher[T] interface for type-safe expectations; AnyMatcher is provided for situations where the compatible types for a matcher cannot be enforced at compile-time.
When implementing an AnyMatcher, it is important to ensure that the matcher fails a test if it is not used correctly, i.e. if the matcher is not compatible with the type of the value being tested.
An AnyMatcher must be used with the Expect().Should() matching function; they may also be used with Expect(got).To() where the got value is of type `any`, though this is not recommended.
NOTE: This interface is not referenced by the test package; the declaration is provided for documentation purposes only.
type FakeResult ¶ added in v0.8.0
FakeResult[R] is a generic type that can be used to help fake a function returning some result type R and/or an error. It can be useful for creating simple fakes for functions or interface methods.
The type does not provide any mechanism for providing an implementation of a function, but facilitates a consistent pattern for simple fakes and minimises the amount of boilerplate code required to create them.
Limitations ¶
No mechanism is provided for configuring expected calls, capturing or testing for expected arguments, or returning different values for multiple calls. FakeResult[R] is for simple cases where a fake function or method consistently returns a specific result.
For cases requiring more advanced capabilities, consider using test.MockFn[A, R].
Example: Mocking an interface with a single method ¶
type MyInterface interface {
MyMethod() (int, error)
}
type fakeMyMethodInterface struct {
FakeResult[int]
}
func (fake *MyFake) MyMethod() (int, error) {
return fake.Result, fake.Err
}
// FakeResult[R] implements Reset(); embedding promotes the Reset method
// to the fakeMyMethodInterface struct itself.
If mocking an interface with multiple methods, the fakeMyMethodInterface struct would implement an explicit Reset() method to reset all FakeResult[R] fields individually.
Returning Multiple Values ¶
When faking an interface method that returns multiple result values (in addition to an error), use a struct type with fields for each of the result values.
type MyInterface interface {
MyMethod() (int, string, error)
}
type fakeMyMethod struct {
fakeMyMethodFn FakeResult[struct{name string; age int}]
}
func (fake *fakeMyMethod) MyMethod() (int, string, error) {
fn := fake.fakeMyMethodFn
return fn.Result.age, fn.Result.name, fn.Err
}
Return Value(s) with No Error ¶
When faking a function that returns only result values and no error, simply ignore the Err field.
Returning Only an Error ¶
When faking a function that only returns an error, use FakeResult[error]. This provides a FakeResult with a Result type of error in addition to the Err field; the Result field should be ignored.
The use of the error type as the Result type clarifies the intent of the fake and avoids confusiion. Consider:
func (s MyStruct) SomeMethod() error {
return s.SomeMethodFn.Err
}
It is clear at this point that the SomeMethodFn field is a FakeResult where only the error is relevant, and the Result field is ignored. This is a common pattern when faking methods that return only an error.
Now consider the possibilities when declaring the SomeMethodFn field:
s.SomeMethodFn := FakeResult[any]{} // does this fake a function returning any or is the Result ignored? s.SomeMethodFn := FakeResult[error]{} // this fake is clearly for a function returning (only) an error
The SomeMethodFn field is a FakeResult; since the Result field is ignored, the type parameter R can be any type, but using FakeResult[error] makes it clear that the fake is for a function that returns an error, even though the Result field, to which the type parameter 'error' relates, is ignored.
func (*FakeResult[R]) Reset ¶ added in v0.8.0
func (fake *FakeResult[R]) Reset()
Reset resets the fake to its zero value.
func (*FakeResult[R]) Returns ¶ added in v0.8.0
func (fake *FakeResult[R]) Returns(v ...any)
Returns sets the result value and/or error to be returned by the fake.
The first R value in the variadic parameter list is used to set the result value, and the first error value is used to set the error. nil values are ignored. A value of any other type will cause the current test to fail as invalid.
R and error values may be specified in any order, but for symmetry it is recommended that they are specified in the order they will be returned.
e.g. when faking a function:
func MyFunc() (int, error)
fakeMyFuncFn := &FakeResult[int]{}
fakeMyFuncFn.Returns(42, nil) // fakes a function returning (42, nil)
If multiple R or error values are provided, the function will fail the current test as invalid.
type FlakyOption ¶ added in v0.11.0
type FlakyOption func(*flakyRunner)
FlakyOption is an option function type for an option that modifies the behavior of a FlakyTest
func MaxAttempts ¶ added in v0.11.0
func MaxAttempts(n uint) FlakyOption
MaxAttempts sets the maximum number of attempts for a FlakyTest.
If the test does not pass within the specified number of attempts, it will fail with a report detailing all failed attempts.
The default is 3 attempts.
MaxAttempts is ignored if the MaxDuration is reached before the number of attempts reaches the maximum.
Setting MaxAttempts to 0 (zero) will allow the test to run indefinitely until it passes, MaxDuration is reached, or the 'go test' timeout is reached.
func MaxDuration ¶ added in v0.11.0
func MaxDuration(d time.Duration) FlakyOption
MaxDuration sets the maximum duration for a FlakyTest.
If the test does not pass within the specified duration, it will fail with a report detailing all failed attempts.
The default is 1 second.
MaxDuration is ignored if MaxAttempts is reached before the duration.
Setting MaxDuration to 0 (zero) will allow the test to run indefinitely until it passes, MaxAttempts is reached, or the 'go test' timeout is reached.
func WaitBetweenAttempts ¶ added in v0.11.0
func WaitBetweenAttempts(d time.Duration) FlakyOption
WaitBetweenAttempts sets the duration to wait between attempts for a FlakyTest.
The default is 10ms.
type HelperScenario ¶ added in v0.10.0
type Matcher ¶ added in v0.8.0
Matcher is a generic interface that describes the method set of a type-safe matcher for testing values of a specific type, T.
A type-safe matcher is not necessarily generic. A matcher that implements Match(got X, opts ...any) bool, where X is a formal, literal type (i.e. not generic) is also a type-safe matcher.
`Matcher[T]` describes the general form of a type-safe matcher.
Generic Matchers ¶
A type-safe matcher that implements support for a specific type is limited to only testing values of that explicit type.
A generic matcher uses type constraints to specify a set of compatible types for the matcher, enabling that matcher to be used with a variety of types.
For example, the equals.Matcher[T comparable] may be used to test, values of any type that is comparable (supports comparison using ==).
NOTE: This interface is not referenced by the test package; the declaration is provided for documentation purposes only.
func BeError ¶ added in v0.13.0
BeError returns a matcher that checks if the value is an error of the expected type.
The matcher may be used in two modes:
When called with an expected error value and type E of `error`, the test will pass if the subject is a non-nil error that satisfies errors.Is for the expected error;
When called with no expected error value and a specific type E (that implements `error`), the test will pass if the subject is a non-nil error that satisfies errors.As for the type E.
Calling BeError with 2 or more error values is invalid and will cause the test to fail with an appropriate error message.
Alternatives ¶
To perform further tests on a value that passes this check using a strongly typed value of type E, use:
expect.Error[E](err) // returns an E and an indicator whether the test passed
// or failed, without halting test execution on failure
require.Error[E](err) // returns an E when the test passes; halts current test
// execution when the test fails, avoiding the need
// for a returned indicator
Example ¶
test.Example()
err := fmt.Errorf("an error occurred: %w", MyError{"invalid argument"})
// this test will pass:
Expect(err).To(BeError[MyError]())
Expect(err).ToNot(BeError[*fs.PathError]())
// these tests will fail:
Expect(error(nil)).To(BeError[error]())
Expect(err).To(BeError[*fs.PathError]())
Output: expected: error got : nil expected: *fs.PathError got : *fmt.wrapError
type Mock ¶ added in v0.4.0
Mock is an interface describing the methods required to be supported by a mock that can be tested using ExpectationsWereMet().
type MockFn ¶ added in v0.7.0
type MockFn[A comparable, R any] struct { // contains filtered or unexported fields }
MockFn is a generic type that can be used to mock a function returning some result (type R) and/or an error, with a value (type A) to capture arguments.
MockFn has two modes of operation:
Expected Calls: calls are configured using a fluent configuration API starting with an ExpectCall method, optionally configuring any expected arguments and te result and/or error to be returned. In this mode, the mock will fail to meet expectations if arguments recorded with actual calls do not match the arguments for the corresponding expected call.
Mapped Results: results for a given set of arguments are configured using the WhenCalledWith method. In this mode, the mock will fail to meet expectations if all configured argument:result combinations are not used.
An implementation of the function being mocked must be provided by the test code to record calls to the mock function and to return the configured result and/or error using either ExpectedResult (expected calls) or ResultFor (mapped results) methods.
The type can be used in a variety of ways to suit the requirements of the mock in a particular test scenario.
TL;DR: Simple Fakes ¶
When the following conditions apply, consider using the simpler test.Fake[R] type:
- the number and order of calls to the mocked function is not significant - the arguments used to call the mocked function are not significant - the return value (and/or error) of the mocked function is consistent across all calls
Mocking Return Values (Fake) ¶
The R type parameter is used to specify the return type of the function being mocked. The WillReturn method can be used to specify the return value that the mock function should return for an expected call.
When mocking a function that returns only an error, specify a result type of any and ignore the Result field.
When mocking a function that returns multiple result values (in addition to an error), use a struct type to specify the return type, with fields for each of the result values.
Testing and Recording Arguments (Spy) ¶
MockFn does not implement the function being mocked; the test code must provide the implementation, which should record each call to the MockFn using RecordCall(), specifying any arguments.
If the method being mocked accepts multiple arguments, they may be captured using a struct type for the A type parameter, with fields for each of the arguments to be captured.
Similarly, when mocking an interface method that returns multiple result values (in addition to an error), a struct type may be used for the R type parameter, with fields for each of the result values.
When mocking a method which accepts no arguments, or if not interested in the arguments, then you may use type any for the A type parameter, or consider using the simpler test.Fake[R] type instead.
Similarly, when mocking function that returns only result values and no error simply ignore the Err field. To fake a method that returns only an error, specify a result type of any and ignore the Result field.
Example ¶
type MyInterface interface {
MyMethod() (int, error)
MyMethodWithArgs(id string, opt bool) (int, error)
}
type myMock struct {
myMethod test.Fake[int]
myMethodWithArgs test.MockFn[struct{ID string; Opt bool}, int]
}
func (mock *myMock) MyMethod() (int, error) {
return mock.myMethod.Result, mock.myMethod.Err
}
func (mock *myMock) MyMethodWithArgs(id string, opt bool) (int, error) {
return mock.myMethodWithArgs.CalledWith(struct{ID string; Opt bool}{ID: id, Opt: opt})
}
func (*MockFn[A, R]) ExpectCall ¶ added in v0.7.0
func (mock *MockFn[A, R]) ExpectCall() *mockFnCall[A, R]
func (*MockFn[A, R]) ExpectationsWereMet ¶ added in v0.7.0
ExpectationsWereMet returns an error if any expectations were not met; otherwise nil.
This method is typically called at the end of a test to ensure that all expected calls were made.
If the mock function is configured for mapped results, this method will return an error if any results were not used.
errors ¶
ErrExpectationsNotMet // one or more expectations were not met; the error is
// joined with errors for each unmet expectation
func (*MockFn[A, R]) RecordCall ¶ added in v0.7.0
RecordCall is used by a mock implementation to record a call to a mock function, optionally testing that arguments match those expected and returning the result and error configured for the expected call.
returns ¶
Returns mock.expected.Result for an expected call; if there is no expected call the zero value of the R type parameter is returned with ErrUnexpectedCall.
If the arguments do not match the expected call, mock.expected.Result is returned with ErrUnexpectedArgs.
errors ¶
ErrUnexpectedCall the call has no corresponding expected call ErrUnexpectedArgs the arguments do not match the expected call mock.expected.Err the error specified for the expected call (if any)
example ¶
type MyInterface interface {
MyMethod(int) (int, error)
}
type myMock struct {
myMethod test.MockFn[int, int]
}
func (mock *myMock) MyMethod(arg int) (int, error) {
return mock.myMethod.RecordCall(arg)
}
Multiple Return Values ¶
When a mocked function returns multiple values (in addition to an error), the return value will typically be a struct with fields for each of the result values.
The struct fields must be returned as individual return values by the mock implementation:
func (mock *myMock) IntDiv(num, div int) (struct{Result, Remainder int}, error) {
result, err := mock.intDiv.RecordCall(any)
return result.Result, result.Remainder, err
}
func (*MockFn[A, R]) Reset ¶ added in v0.7.0
func (mock *MockFn[A, R]) Reset()
Reset sets the mock function to its zero value (no errors, no expected or recorded calls and no mapped results).
func (*MockFn[A, R]) ResultFor ¶ added in v0.7.0
func (mock *MockFn[A, R]) ResultFor(args A) FakeResult[R]
ResultFor returns the Fake[R] value configured for the specified arguments. This method is called by a mock implementation to return the result and/or error configured for a specific set of arguments.
errors ¶
In the event of an error, the function will panic with one of the following errors:
ErrInvalidOperation // when the mock function is configured for expected calls ErrNoResultForArgs // when no result is configured for the specified arguments
func (*MockFn[A, R]) WhenCalledWith ¶ added in v0.7.0
func (mock *MockFn[A, R]) WhenCalledWith(args A) *FakeResult[R]
WhenCalledWith is used to configure the result for a specific set of arguments. This is useful when configuring a test where the result of a mocked function call depends on the arguments passed to the function but the arguments themselves, the number of times the function is called, or the order in which calls to the function are made are not significant.
Only one results can be configured for a given set of arguments.
If the arguments, the number and/or order of calls are significant or if different results are required to be mocked for different calls with the same arguments, use ExpectCall to configure expected calls instead.
Mocked results mapped to arguments may not be combined with expected calls.
returns ¶
Returns a Fake[R] value that can be used to configure the result and/or error for the specified arguments.
errors ¶
In the event of an error, the function will panic with one of the following errors:
ErrInvalidOperation // when the mock function already has one or more expected calls
// configured
ErrInvalidArgument // when a result is already configured for the specified arguments
type R ¶ added in v0.8.0
type R struct {
// value recovered if the test execution caused a panic
Recovered any
// captured stdout output from the test function (the test failure report)
Report []string
// captured stderr output from the test function (logs emitted by the test)
Log []string
// test outcome
// (test.Passed, test.Failed, test.Panicked)
Outcome test.Outcome
// names of any tests that failed
FailedTests []string
// Stack is the stack trace captured when recovering from a panicked test
// or nil if the test did not panic
Stack []byte
// contains filtered or unexported fields
}
R is a struct that contains the result of executing a test function.
func TestHelper ¶ added in v0.10.0
func TestHelper(f func()) R
TestHelper runs a function that executes a function in an internal test runner, independent of the current test, returning an R value that captures the following:
- the test outcome (test.Passed, test.Failed, test.Panicked)
- names of any tests that failed
- stdout output
- stderr output
- any value recovered from a panic
This function is intended to be used to test helper functions. For example, it is used extensively in the blugnu/test package itself, to test the test framework.
func (*R) Expect ¶ added in v0.8.0
Expect verifies that the test result (R) matches the expected outcome.
At least one argument must be provided to Expect() to specify the expected outcome of the test. The arguments can be:
- a test.Outcome value (test.Passed, test.Failed, test.Panicked) - a string or slice of strings that are expected to be present in the test report - a combination of the above, with options to control the assertion behavior
The function will check the test outcome, the test report, and any recovered value from a panic, and will fail the test if any of the expectations are not met.
Currently, any additional output to stdout produced by the test function is ignored and must not be specified in any expected test report.
If no arguments are provided, Expect() will fail the test with an error message indicating that at least one expected outcome or report line is required.
If the test outcome is expected to be test.Panicked, the first argument must be a test.Outcome value (test.Panicked) with a single string argument that is expected to match the string representation (%v) of the value recovered from the panic.
func (*R) ExpectInvalid ¶ added in v0.8.0
ExpectInvalid verifies that the test result (R) indicates an invalid test; that is, the test.Invalid() function was called during evaluation of the test, indicating some problem that makes the test result unreliable or meaningless.
When called without arguments it verifies that the test outcome is failed and that the test report consists only of the '<== INVALID TEST' label. i.e. if any additional report lines are present in the test report then the ExpectInvalid() call will itself fail.
If the test report is not significant to a test, it must be explicitly ignored by passing the opt.IgnoreReport(true) option:
result.ExpectInvalid(opt.IgnoreReport(true))
Invalid Tests ¶
The Go standard library testing framework does not provide a way to mark a test as invalid; the test.Invalid() function fails a test and emits a message labelled with '<== INVALID TEST'.
When testing for an invalid test:
- the test outcome is expected to be test.Failed - the test report is expected to start with the '<== INVALID TEST' label - the test report is expected to contain any report lines specified
func (*R) ExpectWarning ¶ added in v0.10.0
ExpectWarning verifies that the test result (R) contains a warning; that is, the test.Warning() function was called during evaluation of the test.
func (*R) TestPassed ¶ added in v0.13.0
TestPassed checks that there were no failed tests and no report
type Resetter ¶ added in v0.4.0
type Resetter interface {
Reset()
}
Resetter is an interface that describes the Reset method. A Resetter is any type that can be reset to some initial state.
type Runnable ¶ added in v0.10.0
type Runnable interface {
Run()
}
Runnable is an interface implemented by types that can be executed in a test frame using the Run function provided by the interface.
type TestExecutor ¶ added in v0.10.0
TestExecutor is an interface that defines a function to execute a test case
func For ¶ added in v0.10.0
func For[T any](exec func(string, T)) TestExecutor[T]
For creates a TestExecutor that uses the provided function to execute each test case. The function is called with the name of the test case and the test case data. This allows for variations in test execution based on the test case name, which can be useful for more complex test scenarios.
func ForEach ¶ added in v0.10.0
func ForEach[T any](exec func(T)) TestExecutor[T]
ForEach creates a TestExecutor that uses the provided function to execute each test case. The function is called with the test case data, and the test case name is not provided.
type TestingT ¶ added in v0.8.0
type TestingT interface {
Cleanup(fn func())
Name() string
Run(name string, fn func(t *testing.T)) bool
Error(args ...any)
Errorf(s string, args ...any)
Fail()
FailNow()
Failed() bool
Fatal(args ...any)
Fatalf(s string, args ...any)
Helper()
Parallel()
Setenv(name string, value string)
SkipNow()
}
func GetT ¶ added in v0.8.0
func GetT() TestingT
GetT retrieves the *testing.T for the calling test frame, by calling T().
GetT is provided for use where calling the T() function directly is not possible, e.g. due to a name collision with a generic type parameter.
func T ¶ added in v0.8.0
func T() TestingT
T retrieves the TestRunner for the calling test frame. When running in a test frame, this will return the *testing.T for the test.
The T is returned as a TestingT interface; this provides all of the functionality of the *testing.T type, but allows for more flexibility in the test package.
Source Files
¶
- cleanup.go
- errors.go
- expectation.go
- fail.go
- fake.go
- match-boolean.go
- match-bytes.go
- match-context.go
- match-emptiness.go
- match-equals.go
- match-errors-and-panics.go
- match-expectations-were-met.go
- match-length.go
- match-maps.go
- match-nil.go
- match-ordered.go
- match-slices.go
- match-string.go
- match-typecheck.go
- mock-fn.go
- parallel.go
- pkgdocs.go
- record.go
- reset.go
- restore.go
- run.go
- runnable-flaky.go
- runnable-helper-tests.go
- runnable-test.go
- runnable-testcases.go
- skip-now.go
- stop-watch.go
- test-helper.go
- testframe.go
- type.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package expect provides non-fatal assertions that operate on a subject value.
|
Package expect provides non-fatal assertions that operate on a subject value. |
|
matchers
|
|
|
Package opt provides type options for expectations and matchers.
|
Package opt provides type options for expectations and matchers. |
|
Package require provides conclusory type assertion functions that operate on a subject value.
|
Package require provides conclusory type assertion functions that operate on a subject value. |