vermock

package module
v0.0.0-...-b8d801a Latest Latest
Warning

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

Go to latest
Published: Jan 10, 2024 License: MIT Imports: 5 Imported by: 0

README

vermock module

Go Reference Go Report Go Coverage

Tired of mocking libraries with cumbersome APIs? Frustrated with numerous and complicated options? Looking for a mock that works well with a composite of small interfaces or loves high ordered functions? Introducing vermock, the simple mocking support that will enthusiastically accept a function that can be tailored to any bespoke test case. vermock is guided by a central principle: test code must have full control of the code that runs in the mocked object. This means mock behaviour has access to anything in the test fixture and the testing.T value. This module provides a number functions that can be used as building blocks for your own mocks.

Installation

To use the vermock module, ensure it is installed and imported in your project.

import vermock "github.com/Versent/go-vermock"

To use the vermockgen command, simply run go run:

go run github.com/Versent/go-vermock/cmd/vermockgen

After running vermockgen for the first time, go generate can be used to regenerate generated files:

go generate

Basic Usage

  1. Define an Interface

Create one or more interfaces that your mock needs to satisfy. For example:

package my

type Getter interface {
	Get(key string) (any, bool)
}

type Putter interface {
	Put(key string, value any) error
}
  1. Create a Mock Implementation

Implement the interface with mock methods. For example:

type mockObject struct {
	_ byte // prevent zero-sized type
}

func (m *mockObject) Get(key string) (any, bool) {
	return vermock.Call2[any, bool](m, "Get", key)
}

func (m *mockObject) Put(key string, value any) error {
	return vermock.Call1[error](m, "Put", key, value)
}

Note that vermock.New will panic if a zero-sized type is constructed more than once.

  1. (Optional) Define Helpers

Implement Expect functions for greater readability. For example:

func ExpectGet(delegate func(testing.TB, string) (any, bool)) func(*mockObject) {
	return vermock.Expect[mockObject]("Get", delegate)
}

func ExpectPut(delegate func(testing.TB, string, any) error) func(*mockObject) {
	return vermock.Expect[mockObject]("Put", delegate)
}
  1. Using the Mock in Tests

Create a mock instance in your test and use it as needed. For instance:

func TestObject(t *testing.T) {
	m := vermock.New(t,
	vermock.ExpectGet(func(t testing.TB, key string) (any, bool) {
		// Define your mock's behaviour
	}),
	vermock.ExpectPut(func(t testing.TB, key string, value any) error {
		// Define your mock's behaviour
	}),
)

	// Use the mock instance in your test

	// Assert that all expected methods were called
	vermock.AssertExpectedCalls(t, m)
}
Using vermockgen

Alternatively, creating a mock implementation and associated helpers can be automated with vermockgen. Instead of implementing all the methods of your mock, simply declare the interfaces you want your mock to satisfy in an ordinary go file and let vermockgen do the rest.

To continue the example from above this file would look like:

//go:build vermockstub

package my

type mockObject struct {
	Getter
	Putter
}

This is an ordinary go source file with a special build tag: vermockstub. After running vermockgen (see Installation above) a new file called vermock_gen.go will be created with a new definition of mockObject (the build tag ensures that these two definitions do not collide) containing all the generated methods and functions.

Beyond Basic Usage

Be sure to checkout the Examples in the tests.

Expect Variants

In addition to the vermock.Expect function, which corresponds to a single call of a method, there is also vermock.ExpectMany, which will consume all remaining calls of a method.

Expect functions accepts a delegate function that matches the signature of the named method. The delegate may also accept a *testingT or testing.TB value as the first argument. This the same testing.T that was used to construct the mock (first argument to vermock.New). In addition, ExpectMany optionally accepts the method's call count.

Ordered Calls

The vermock.ExpectInOrder will ensure that calls occur in a specified order. For example, this will fail if Put is called before Get:

vermock.New(t, vermock.ExpectInOrder(vermock.Expect("Get", ...), vermock.Expect("Put", ...)))

Documentation

Overview

Package vermock provides a flexible and functional mocking framework for Go tests.

Example (AllowRepeatedCalls)
package main

import (
	"fmt"
	"testing"

	vermock "github.com/Versent/go-vermock"
)

// Cache contains a variety of methods with different signatures.
type Cache interface {
	Put(string, any) error
	Get(string) (any, bool)
	Delete(string)
	Load(...string)
}

// mockCache is a mock implementation of Cache.  It can be anything, but
// zero-sized types are problematic.
type mockCache struct {
	_ byte
}

// Put returns one value, so use vermock.Call1.
func (m *mockCache) Put(key string, value any) error {
	return vermock.Call1[error](m, "Put", key, value)
}

// Get returns two values, so use vermock.Call2.
func (m *mockCache) Get(key string) (any, bool) {
	return vermock.Call2[any, bool](m, "Get", key)
}

// Delete returns no values, so use vermock.Call0.
func (m *mockCache) Delete(key string) {
	vermock.Call0(m, "Delete", key)
}

// Load is variadic, the last argument must be passed as a slice to one of the
// vermock.CallN functions.
func (m *mockCache) Load(keys ...string) {
	vermock.Call0(m, "Load", keys)
}

func main() {
	t := &testing.T{} // or any testing.TB, your test does not create this
	// 1. Create a mock object with ExpectMany.
	var cache Cache = vermock.New(t,
		// delegate function may receive a call counter and the method arguments
		vermock.ExpectMany[mockCache]("Load", func(n vermock.CallCount, keys ...string) {
			fmt.Println("load", n, keys)
		}),
		// and testing.TB
		vermock.ExpectMany[mockCache]("Load", func(t testing.TB, n vermock.CallCount, keys ...string) {
			fmt.Println("load", n, keys)
		}),
		// or *testing.T
		vermock.ExpectMany[mockCache]("Load", func(t *testing.T, n vermock.CallCount, keys ...string) {
			fmt.Println("load", n, keys)
		}),
		// or only testing.TB/*testing.T
		vermock.ExpectMany[mockCache]("Load", func(t testing.TB, keys ...string) {
			fmt.Println("load 3", keys)
		}),
		// or only the method arguments
		vermock.ExpectMany[mockCache]("Load", func(keys ...string) {
			fmt.Println("load 4", keys)
		}),
	)
	// 2. Use the mock object in your code under test.
	cache.Load("foo", "bar")
	cache.Load("baz")
	cache.Load("foo")
	cache.Load("bar")
	cache.Load("baz")
	cache.Load("foo", "bar", "baz")
	// 3. Assert that all expected methods were called.
	vermock.AssertExpectedCalls(t, cache)
	// mock will not fail the test because ExpectMany allows repeated calls.
	fmt.Println("more than expected:", t.Failed())
}
Output:

load 0 [foo bar]
load 1 [baz]
load 2 [foo]
load 3 [bar]
load 4 [baz]
load 4 [foo bar baz]
more than expected: false
Example (MixedOrderedCalls)
package main

import (
	"fmt"
	"testing"

	vermock "github.com/Versent/go-vermock"
)

// Cache contains a variety of methods with different signatures.
type Cache interface {
	Put(string, any) error
	Get(string) (any, bool)
	Delete(string)
	Load(...string)
}

// mockCache is a mock implementation of Cache.  It can be anything, but
// zero-sized types are problematic.
type mockCache struct {
	_ byte
}

// Put returns one value, so use vermock.Call1.
func (m *mockCache) Put(key string, value any) error {
	return vermock.Call1[error](m, "Put", key, value)
}

// Get returns two values, so use vermock.Call2.
func (m *mockCache) Get(key string) (any, bool) {
	return vermock.Call2[any, bool](m, "Get", key)
}

// Delete returns no values, so use vermock.Call0.
func (m *mockCache) Delete(key string) {
	vermock.Call0(m, "Delete", key)
}

// Load is variadic, the last argument must be passed as a slice to one of the
// vermock.CallN functions.
func (m *mockCache) Load(keys ...string) {
	vermock.Call0(m, "Load", keys)
}

func main() {
	t := &exampleT{} // or any testing.TB, your test does not create this
	// 1. Create a mock object with ExpectInOrder.
	get := vermock.Expect[mockCache]("Get", func(key string) (any, bool) {
		return "bar", true
	})
	put := vermock.Expect[mockCache]("Put", func(key string, value any) error {
		return nil
	})
	var cache Cache = vermock.New(t,
		get, put,
		vermock.ExpectInOrder(put, get),
		get, put,
	)
	// 2. Use the mock object in your code under test.
	for i := 0; i < 3; i++ {
		cache.Put(fmt.Sprint("foo", i), "bar")
		cache.Get(fmt.Sprint("foo", i))
	}
	// 3. Assert that all expected methods were called.
	vermock.AssertExpectedCalls(t, cache)
	// mock will not fail the test
	fmt.Println("less than expected:", t.Failed())
}

type exampleT struct {
	testing.T
}

func (t *exampleT) Fatal(args ...any) {
	fmt.Println(args...)
	t.T.FailNow()
}

func (t *exampleT) Fatalf(format string, args ...any) {
	fmt.Printf(format+"\n", args...)
	t.T.FailNow()
}

func (t *exampleT) Error(args ...any) {
	fmt.Println(args...)
	t.T.Fail()
}

func (t *exampleT) Errorf(format string, args ...any) {
	fmt.Printf(format+"\n", args...)
	t.T.Fail()
}

func (t *exampleT) Log(args ...any) {
	fmt.Println(args...)
}

func (t *exampleT) Logf(format string, args ...any) {
	fmt.Printf(format+"\n", args...)
}
Output:

call to Put: 0/0
call to Get: 0/0
call to Put: 1/1
call to Get: 1/2
call to Put: 2/2
call to Get: 2/2
less than expected: false
Example (OrderedCalls)
package main

import (
	"fmt"
	"testing"

	vermock "github.com/Versent/go-vermock"
)

// Cache contains a variety of methods with different signatures.
type Cache interface {
	Put(string, any) error
	Get(string) (any, bool)
	Delete(string)
	Load(...string)
}

// mockCache is a mock implementation of Cache.  It can be anything, but
// zero-sized types are problematic.
type mockCache struct {
	_ byte
}

// Put returns one value, so use vermock.Call1.
func (m *mockCache) Put(key string, value any) error {
	return vermock.Call1[error](m, "Put", key, value)
}

// Get returns two values, so use vermock.Call2.
func (m *mockCache) Get(key string) (any, bool) {
	return vermock.Call2[any, bool](m, "Get", key)
}

// Delete returns no values, so use vermock.Call0.
func (m *mockCache) Delete(key string) {
	vermock.Call0(m, "Delete", key)
}

// Load is variadic, the last argument must be passed as a slice to one of the
// vermock.CallN functions.
func (m *mockCache) Load(keys ...string) {
	vermock.Call0(m, "Load", keys)
}

func main() {
	t := &testing.T{} // or any testing.TB, your test does not create this
	// 1. Create a mock object with ExpectInOrder.
	var cache Cache = vermock.New(t,
		vermock.ExpectInOrder(
			vermock.Expect[mockCache]("Put", func(key string, value any) error {
				fmt.Println("put", key, value)
				return nil
			}),
			vermock.Expect[mockCache]("Get", func(key string) (any, bool) {
				fmt.Println("get", key)
				return "bar", true
			}),
		),
	)
	// 2. Use the mock object in your code under test.
	cache.Get("foo")
	cache.Put("foo", "bar")
	// 3. Assert that all expected methods were called.
	vermock.AssertExpectedCalls(t, cache)
	// mock will fail the test because the call to Get is before the call
	// to Put.
	fmt.Println("less than expected:", t.Failed())
}
Output:

get foo
put foo bar
less than expected: true
Example (Pass)
package main

import (
	"fmt"
	"testing"

	vermock "github.com/Versent/go-vermock"
)

// Cache contains a variety of methods with different signatures.
type Cache interface {
	Put(string, any) error
	Get(string) (any, bool)
	Delete(string)
	Load(...string)
}

// mockCache is a mock implementation of Cache.  It can be anything, but
// zero-sized types are problematic.
type mockCache struct {
	_ byte
}

// Put returns one value, so use vermock.Call1.
func (m *mockCache) Put(key string, value any) error {
	return vermock.Call1[error](m, "Put", key, value)
}

// Get returns two values, so use vermock.Call2.
func (m *mockCache) Get(key string) (any, bool) {
	return vermock.Call2[any, bool](m, "Get", key)
}

// Delete returns no values, so use vermock.Call0.
func (m *mockCache) Delete(key string) {
	vermock.Call0(m, "Delete", key)
}

// Load is variadic, the last argument must be passed as a slice to one of the
// vermock.CallN functions.
func (m *mockCache) Load(keys ...string) {
	vermock.Call0(m, "Load", keys)
}

// ExpectDelete is a helper function that hides the stringiness of vermock.
func ExpectDelete(delegate func(t testing.TB, key string)) func(*mockCache) {
	return vermock.Expect[mockCache]("Delete", delegate)
}

func main() {
	t := &exampleT{} // or any testing.TB, your test does not create this
	// 1. Create a mock object with expected calls.
	var cache Cache = vermock.New(t,
		// delegate function can receive testing.TB
		vermock.Expect[mockCache]("Get", func(t testing.TB, key string) (any, bool) {
			return "bar", true
		}),
		vermock.Expect[mockCache]("Put", func(t testing.TB, key string, value any) error {
			return nil
		}),
		// or only the method arguments
		vermock.Expect[mockCache]("Delete", func(key string) {}),
		// you may prefer to define a helper function
		ExpectDelete(func(t testing.TB, key string) {}),
	)
	// 2. Use the mock object in your code under test.
	cache.Put("foo", "bar")
	cache.Get("foo")
	cache.Delete("foo")
	cache.Delete("foo")
	// 3. Assert that all expected methods were called.
	vermock.AssertExpectedCalls(t, cache)
	// mock will not fail the test
	fmt.Println("less than expected:", t.Failed())
}

type exampleT struct {
	testing.T
}

func (t *exampleT) Fatal(args ...any) {
	fmt.Println(args...)
	t.T.FailNow()
}

func (t *exampleT) Fatalf(format string, args ...any) {
	fmt.Printf(format+"\n", args...)
	t.T.FailNow()
}

func (t *exampleT) Error(args ...any) {
	fmt.Println(args...)
	t.T.Fail()
}

func (t *exampleT) Errorf(format string, args ...any) {
	fmt.Printf(format+"\n", args...)
	t.T.Fail()
}

func (t *exampleT) Log(args ...any) {
	fmt.Println(args...)
}

func (t *exampleT) Logf(format string, args ...any) {
	fmt.Printf(format+"\n", args...)
}
Output:

call to Put: 0/0
call to Get: 0/0
call to Delete: 0/0
call to Delete: 1/0
less than expected: false
Example (UnexpectedCall)
package main

import (
	"fmt"
	"testing"

	vermock "github.com/Versent/go-vermock"
)

// Cache contains a variety of methods with different signatures.
type Cache interface {
	Put(string, any) error
	Get(string) (any, bool)
	Delete(string)
	Load(...string)
}

// mockCache is a mock implementation of Cache.  It can be anything, but
// zero-sized types are problematic.
type mockCache struct {
	_ byte
}

// Put returns one value, so use vermock.Call1.
func (m *mockCache) Put(key string, value any) error {
	return vermock.Call1[error](m, "Put", key, value)
}

// Get returns two values, so use vermock.Call2.
func (m *mockCache) Get(key string) (any, bool) {
	return vermock.Call2[any, bool](m, "Get", key)
}

// Delete returns no values, so use vermock.Call0.
func (m *mockCache) Delete(key string) {
	vermock.Call0(m, "Delete", key)
}

// Load is variadic, the last argument must be passed as a slice to one of the
// vermock.CallN functions.
func (m *mockCache) Load(keys ...string) {
	vermock.Call0(m, "Load", keys)
}

func main() {
	t := &testing.T{} // or any testing.TB, your test does not create this
	// 1. Create a mock object with expected calls.
	var cache Cache = vermock.New(t,
		// delegate function can receive testing.TB
		vermock.Expect[mockCache]("Put", func(t testing.TB, key string, value any) error {
			fmt.Println("put", key, value)
			return nil
		}),
		// or only the method arguments
		vermock.Expect[mockCache]("Delete", func(key string) {
			fmt.Println("delete", key)
		}),
	)
	// 2. Use the mock object in your code under test.
	cache.Put("foo", "bar")
	cache.Get("foo")
	cache.Delete("foo")
	// 3. Assert that all expected methods were called.
	vermock.AssertExpectedCalls(t, cache)
	// mock will fail the test because the call to Get is not expected.
	fmt.Println("more than expected:", t.Failed())
}
Output:

put foo bar
delete foo
more than expected: true
Example (UnmetExpectation)
package main

import (
	"fmt"
	"testing"

	vermock "github.com/Versent/go-vermock"
)

// Cache contains a variety of methods with different signatures.
type Cache interface {
	Put(string, any) error
	Get(string) (any, bool)
	Delete(string)
	Load(...string)
}

// mockCache is a mock implementation of Cache.  It can be anything, but
// zero-sized types are problematic.
type mockCache struct {
	_ byte
}

// Put returns one value, so use vermock.Call1.
func (m *mockCache) Put(key string, value any) error {
	return vermock.Call1[error](m, "Put", key, value)
}

// Get returns two values, so use vermock.Call2.
func (m *mockCache) Get(key string) (any, bool) {
	return vermock.Call2[any, bool](m, "Get", key)
}

// Delete returns no values, so use vermock.Call0.
func (m *mockCache) Delete(key string) {
	vermock.Call0(m, "Delete", key)
}

// Load is variadic, the last argument must be passed as a slice to one of the
// vermock.CallN functions.
func (m *mockCache) Load(keys ...string) {
	vermock.Call0(m, "Load", keys)
}

// ExpectDelete is a helper function that hides the stringiness of vermock.
func ExpectDelete(delegate func(t testing.TB, key string)) func(*mockCache) {
	return vermock.Expect[mockCache]("Delete", delegate)
}

func main() {
	t := &testing.T{} // or any testing.TB, your test does not create this
	// 1. Create a mock object with expected calls.
	var cache Cache = vermock.New(t,
		// delegate function can receive testing.TB
		vermock.Expect[mockCache]("Put", func(t testing.TB, key string, value any) error {
			fmt.Println("put", key, value)
			return nil
		}),
		// or *testing.T
		vermock.Expect[mockCache]("Get", func(t *testing.T, key string) (any, bool) {
			fmt.Println("get", key)
			return "bar", true
		}),
		// or only the method arguments
		vermock.Expect[mockCache]("Delete", func(key string) {
			fmt.Println("delete", key)
		}),
		// you may prefer to define a helper function
		ExpectDelete(func(t testing.TB, key string) {
			t.Log("this is not going to be called; causing t.Fail() to be called by vermock.AssertExpectedCalls")
		}),
	)
	// 2. Use the mock object in your code under test.
	cache.Put("foo", "bar")
	cache.Get("foo")
	cache.Delete("foo")
	// 3. Assert that all expected methods were called.
	vermock.AssertExpectedCalls(t, cache)
	// mock will fail the test because the second call to Delete is not met.
	fmt.Println("less than expected:", t.Failed())
}
Output:

put foo bar
get foo
delete foo
less than expected: true

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AssertExpectedCalls

func AssertExpectedCalls(t testing.TB, mocks ...any)

AssertExpectedCalls asserts that all expected callables of all delegates of the given mocks were called.

func Call0

func Call0[T any](key *T, name string, in ...any)

Call0 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return no result values, otherwise the will be marked as a fail and this function will panic.

func Call1

func Call1[T1, T any](key *T, name string, in ...any) (v T1)

Call1 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return one result value, otherwise the will be marked as a fail and this function will return an error when T1 is assignable to an error type, or this function will panic.

func Call2

func Call2[T1, T2, T any](key *T, name string, in ...any) (v1 T1, v2 T2)

Call2 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return two result values, otherwise the will be marked as a fail and this function will return an error when T2 is assignable to an error type, or this function will panic.

func Call3

func Call3[T1, T2, T3, T any](key *T, name string, in ...any) (v1 T1, v2 T2, v3 T3)

Call3 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return three result values, otherwise the will be marked as a fail and this function will return an error when T3 is assignable to an error type, or this function will panic.

func Call4

func Call4[T1, T2, T3, T4, T any](key *T, name string, in ...any) (v1 T1, v2 T2, v3 T3, v4 T4)

Call4 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return four result values, otherwise the will be marked as a fail and this function will return an error when T4 is assignable to an error type, or this function will panic.

func Call5

func Call5[T1, T2, T3, T4, T5, T any](key *T, name string, in ...any) (v1 T1, v2 T2, v3 T3, v4 T4, v5 T5)

Call5 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return 5 result values, otherwise the will be marked as a fail and this function will return an error when T5 is assignable to an error type, or this function will panic.

func Call6

func Call6[T1, T2, T3, T4, T5, T6, T any](key *T, name string, in ...any) (v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6)

Call6 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return 6 result values, otherwise the will be marked as a fail and this function will return an error when T6 is assignable to an error type, or this function will panic.

func Call7

func Call7[T1, T2, T3, T4, T5, T6, T7, T any](key *T, name string, in ...any) (v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7)

Call7 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return 7 result values, otherwise the will be marked as a fail and this function will return an error when T7 is assignable to an error type, or this function will panic.

func Call8

func Call8[T1, T2, T3, T4, T5, T6, T7, T8, T any](key *T, name string, in ...any) (v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8)

Call8 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return 8 result values, otherwise the will be marked as a fail and this function will return an error when T8 is assignable to an error type, or this function will panic.

func Call9

func Call9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T any](key *T, name string, in ...any) (v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8, v9 T9)

Call9 calls the function of the given name for the given mock with the given arguments. If the function is variadic then the last argument must be passed as a slice, otherwise this function panics. The function is expected to return 9 result values, otherwise the will be marked as a fail and this function will return an error when T9 is assignable to an error type, or this function will panic.

func CallDelegate

func CallDelegate[T any](key *T, name string, outTypes []reflect.Type, in ...reflect.Value) (out []reflect.Value)

CallDelegate calls the next Callable of the Delegate with the given name and given arguments. If the delegate is variadic then the last argument must be a slice, otherwise this function panics. If the next Callable does not exist or the last Callable is not MultiCallable, then the mock object will be marked as failed. In the case of a fail and if the delegate function returns an error as its last return value, then the error will be set and returned otherwise the function returns zero values for all of the return values.

func New

func New[T any](t testing.TB, opts ...Option[T]) *T

New creates a new mock object of type T and applies the given options. It panics if a mock for a zero-sized type is constructed more than once.

Types

type CallCount

type CallCount int

type Callable

type Callable interface {
	Call(testing.TB, CallCount, []reflect.Value) []reflect.Value
}

Callable defines an interface for delegates to call test functions.

type Callables

type Callables []Callable

Callables is a slice of Callable objects.

func (Callables) Append

func (c Callables) Append(callable ...Callable) Callables

Append adds one or more Callables to the slice.

func (Callables) Call

func (c Callables) Call(t testing.TB, index CallCount, in []reflect.Value) []reflect.Value

Call invokes the Callable at the given index with the given arguments. Panics if the index is out of range and the last Callable is not a MultiCallable.

func (Callables) Cap

func (c Callables) Cap() int

Cap returns the capacity of the slice of Callables.

func (Callables) Len

func (c Callables) Len() int

Len returns the number of Callables in the slice.

func (Callables) MultiCallable

func (c Callables) MultiCallable() bool

MultiCallable returns true if the last Callable in the slice is a MultiCallable.

type Delegate

type Delegate struct {
	sync.Mutex
	Callables
	// contains filtered or unexported fields
}

Delegate represents a function that is expected to be called.

func (*Delegate) Append

func (d *Delegate) Append(callable ...Callable) Callables

Append adds one or more callables to the delegate.

type Delegates

type Delegates = map[string]*Delegate

Delegates maps function names to their Delegate implementations.

type MultiCallable

type MultiCallable interface {
	MultiCallable() bool
}

MultiCallable defines an interface for Callable objects that can be called multiple times.

type Option

type Option[T any] func(*T)

Option defines a function that configures a mock object.

func Expect

func Expect[T any](name string, fn any) Option[T]

Expect registers a function to be called exactly once when a method with the given name is invoked on the mock object. The function signature of fn must match the named method signature, except that the first argument may optionally be a testing.TB or *testing.T. Panics if fn is not a function.

func ExpectAnyOrder

func ExpectAnyOrder[T any](options ...Option[T]) Option[T]

func ExpectInOrder

func ExpectInOrder[T any](options ...Option[T]) Option[T]

func ExpectMany

func ExpectMany[T any](name string, fn any) Option[T]

ExpectMany registers a function to be called at least once for a method with the given name on the mock object. Like Expect, the arguments of fn must match the named method signature and may optionally be preceded by a testing.TB or *testing.T. In addition, the first argument of fn may optionally be of type CallCount, in such cases fn will be passed the total number of times the method has been called (starting at 0). Panics if fn is not a function.

func Options

func Options[T any](opts ...Option[T]) Option[T]

type Value

type Value struct {
	reflect.Value
	// contains filtered or unexported fields
}

Value is a Callable that wraps a reflect.Value.

func (Value) Call

func (v Value) Call(t testing.TB, i CallCount, in []reflect.Value) []reflect.Value

Call invokes the Callable with the given arguments. If the Callable is variadic, the last argument must be passed as a slice, otherwise this method panics.

Directories

Path Synopsis
cmd
internal

Jump to

Keyboard shortcuts

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