Avnology ID
SDKsGo SDKGuides

Testing

Test Go applications that use the Go SDK with mocks and integration helpers.

Testing

The SDK provides interfaces for mocking in unit tests and helpers for integration testing.

Interface-based mocking

All SDK services implement interfaces, making them easy to mock.

package myservice

import (
    "context"

    avnologyid "github.com/avnology/sdk-go"
)

// Define the interface your code depends on
type PermissionChecker interface {
    Check(ctx context.Context, params *avnologyid.CheckPermissionParams) (bool, error)
}

// Your service accepts the interface, not the concrete client
type ProjectService struct {
    permissions PermissionChecker
}

func (s *ProjectService) UpdateProject(ctx context.Context, userID, projectID string) error {
    allowed, err := s.permissions.Check(ctx, &avnologyid.CheckPermissionParams{
        Subject:  "user:" + userID,
        Relation: "editor",
        Object:   "project:" + projectID,
    })
    if err != nil {
        return err
    }
    if !allowed {
        return fmt.Errorf("permission denied")
    }
    // Update project...
    return nil
}

Mock implementation

package myservice_test

import (
    "context"
    "testing"

    avnologyid "github.com/avnology/sdk-go"
    "github.com/stretchr/testify/assert"
)

type mockPermissions struct {
    checkFn func(ctx context.Context, params *avnologyid.CheckPermissionParams) (bool, error)
}

func (m *mockPermissions) Check(ctx context.Context, params *avnologyid.CheckPermissionParams) (bool, error) {
    return m.checkFn(ctx, params)
}

func TestUpdateProject_Authorized(t *testing.T) {
    svc := &ProjectService{
        permissions: &mockPermissions{
            checkFn: func(_ context.Context, p *avnologyid.CheckPermissionParams) (bool, error) {
                assert.Equal(t, "user:usr_jane", p.Subject)
                assert.Equal(t, "editor", p.Relation)
                return true, nil
            },
        },
    }

    err := svc.UpdateProject(context.Background(), "usr_jane", "proj_abc")
    assert.NoError(t, err)
}

func TestUpdateProject_Denied(t *testing.T) {
    svc := &ProjectService{
        permissions: &mockPermissions{
            checkFn: func(_ context.Context, _ *avnologyid.CheckPermissionParams) (bool, error) {
                return false, nil
            },
        },
    }

    err := svc.UpdateProject(context.Background(), "usr_jane", "proj_abc")
    assert.ErrorContains(t, err, "permission denied")
}

Integration testing

For integration tests against a real instance, use the test helper.

import (
    "testing"

    avnologyid "github.com/avnology/sdk-go"
    "github.com/avnology/sdk-go/testhelper"
)

func TestIntegration_CreateAndListUsers(t *testing.T) {
    if testing.Short() {
        t.Skip("skipping integration test")
    }

    client, err := avnologyid.NewClient(
        avnologyid.WithBaseURL("http://localhost:4455"),
        avnologyid.WithAPIKey(os.Getenv("AVNOLOGY_TEST_API_KEY")),
    )
    require.NoError(t, err)

    helper := testhelper.New(client)
    t.Cleanup(func() { helper.Cleanup(context.Background()) })

    user, err := helper.CreateTestUser(context.Background(), testhelper.TestUserOpts{
        Email:    fmt.Sprintf("test-%d@example.com", time.Now().UnixNano()),
        Verified: true,
    })
    require.NoError(t, err)

    fetched, err := client.Admin.GetUser(context.Background(), &avnologyid.GetUserParams{
        UserID: user.ID,
    })
    require.NoError(t, err)
    assert.Equal(t, user.Email, fetched.Email)
}

See also

On this page