Quick Start v3.7.0
WARNING
⚠️ EXPERIMENTAL FEATURE: The GripMock Embedded SDK is currently experimental. The API is subject to change without notice, and functionality may be modified in future versions. Use at your own risk.
INFO
Minimum Requirements: Go 1.26 or later
Version history: Embedded SDK introduced in v3.7.0 (legacy API:
sdk.Run,mock.Stub,.When,.Reply,.Commit). Current v2 API available since v3.16.0. See the Upgrade Guide for migration.
Get started with GripMock Embedded SDK in your tests.
Basic Example
Here's a simple example:
import (
"testing"
"github.com/stretchr/testify/require"
sdk "github.com/bavix/gripmock/v3/pkg/sdk"
)
func TestMyService_Call(t *testing.T) {
// ARRANGE
srv := sdk.NewServer(t, sdk.WithFileDescriptor(helloworld.File_helloworld_proto))
defer srv.Close()
// Define an expectation
srv.ExpectUnary("/helloworld.Greeter/SayHello").
Match("name", "Alex").
Return("message", "Hi Alex")
client := helloworld.NewGreeterClient(srv.Conn())
// ACT
reply, err := client.SayHello(t.Context(), &helloworld.HelloRequest{Name: "Alex"})
// ASSERT
require.NoError(t, err)
require.Equal(t, "Hi Alex", reply.GetMessage())
}NewServer creates an independent server (safe for t.Parallel()), starts it on a random TCP port, and registers t.Cleanup for auto-verify + close. There is no error return — programmer mistakes panic immediately.
Test Helper Pattern
For better organization, create a helper function:
func runMyServiceMock(t *testing.T) *sdk.Server {
t.Helper()
return sdk.NewServer(t, sdk.WithFileDescriptor(helloworld.File_helloworld_proto))
}
func TestMyService_WithHelper(t *testing.T) {
// ARRANGE
srv := runMyServiceMock(t)
srv.ExpectUnary("/helloworld.Greeter/SayHello").
Match("name", "Alex").
Return("message", "Hi Alex")
client := helloworld.NewGreeterClient(srv.Conn())
// ACT
reply, err := client.SayHello(t.Context(), &helloworld.HelloRequest{Name: "Alex"})
// ASSERT
require.NoError(t, err)
require.Equal(t, "Hi Alex", reply.GetMessage())
}More Complex Example
Here's a more complex example with delay:
import (
"testing"
"time"
"github.com/stretchr/testify/require"
sdk "github.com/bavix/gripmock/v3/pkg/sdk"
)
func TestGreeter_SayHello_WithDelay(t *testing.T) {
// ARRANGE
srv := sdk.NewServer(t, sdk.WithFileDescriptor(helloworld.File_helloworld_proto))
defer srv.Close()
// Define an expectation with delay using composable Delay()
srv.ExpectUnary("/helloworld.Greeter/SayHello").
Match("name", "Bob").
Return(Delay(20*time.Millisecond, "message", "Hello Bob"))
client := helloworld.NewGreeterClient(srv.Conn())
// ACT
start := time.Now()
reply, err := client.SayHello(t.Context(), &helloworld.HelloRequest{Name: "Bob"})
elapsed := time.Since(start)
// ASSERT
require.NoError(t, err)
require.Equal(t, "Hello Bob", reply.GetMessage())
require.GreaterOrEqual(t, elapsed.Milliseconds(), int64(20))
}Legacy API (v3.7.0+)
The same example in the legacy API:
import (
"testing"
"github.com/stretchr/testify/require"
sdk "github.com/bavix/gripmock/v3/pkg/sdk"
)
func TestMyService_Call_Legacy(t *testing.T) {
mock, err := sdk.Run(t, sdk.WithFileDescriptor(helloworld.File_helloworld_proto))
require.NoError(t, err)
defer mock.Close()
mock.Stub(sdk.By("/helloworld.Greeter/SayHello")).
When(sdk.Equals("name", "Alex")).
Reply(sdk.Data("message", "Hi Alex")).
Commit()
client := helloworld.NewGreeterClient(mock.Conn())
reply, err := client.SayHello(t.Context(), &helloworld.HelloRequest{Name: "Alex"})
require.NoError(t, err)
require.Equal(t, "Hi Alex", reply.GetMessage())
}Using Full Method Constants
srv.ExpectUnary(helloworld.Greeter_SayHello_FullMethodName).
Match("name", "Alex").
Return("message", "Hi Alex")WARNING
⚠️ EXPERIMENTAL FEATURE: The GripMock Embedded SDK is currently experimental. The API is subject to change without notice, and functionality may be modified in future versions. Use at your own risk.