From 24c9669cbc23f548a84b351beeea24b6f0e9b441 Mon Sep 17 00:00:00 2001 From: DooomiT Date: Sun, 3 Dec 2023 01:17:43 +0100 Subject: [PATCH] feat: Add basic unit tests --- cmd/local/local.go | 6 +- cmd/serve/serve.go | 6 +- cmd/setup/setup.go | 6 +- go.mod | 1 + go.sum | 2 + internal/service/service_test.go | 125 ++++++++++++++++++++++ internal/tester/postgres.go | 100 +++++++++--------- internal/tester/postgres_test.go | 171 +++++++++++++++++++++++++++++++ internal/tester/tester.go | 6 +- pkg/database/database_mock.go | 137 +++++++++++++++++++++++++ 10 files changed, 500 insertions(+), 60 deletions(-) create mode 100644 internal/service/service_test.go create mode 100644 internal/tester/postgres_test.go create mode 100644 pkg/database/database_mock.go diff --git a/cmd/local/local.go b/cmd/local/local.go index 9f374ca..71e8ac4 100644 --- a/cmd/local/local.go +++ b/cmd/local/local.go @@ -41,8 +41,12 @@ func local(cmd *cobra.Command, args []string) error { LocalCfg.TestTimeout = testTimeout } log.Debug().Msg("Initializing database tester") + dbs := []database.Database{} + for _, dbCfg := range LocalCfg.Databases { + dbs = append(dbs, database.NewPostgres(dbCfg)) + } tester := tester.NewPostgres(tester.Config{ - Databases: LocalCfg.Databases, + Databases: dbs, TestTimeout: LocalCfg.TestTimeout, TestInterval: LocalCfg.TestInterval, }) diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index d457f75..a05fe67 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -51,8 +51,12 @@ func serve(cmd *cobra.Command, args []string) error { serveCfg.TestTimeout = testTimeout } log.Debug().Msg("Initializing database tester") + dbs := []database.Database{} + for _, dbCfg := range serveCfg.Databases { + dbs = append(dbs, database.NewPostgres(dbCfg)) + } tester := tester.NewPostgres(tester.Config{ - Databases: serveCfg.Databases, + Databases: dbs, TestTimeout: serveCfg.TestTimeout, TestInterval: serveCfg.TestInterval, }) diff --git a/cmd/setup/setup.go b/cmd/setup/setup.go index c4a14e1..1fd2648 100644 --- a/cmd/setup/setup.go +++ b/cmd/setup/setup.go @@ -33,8 +33,12 @@ func setup(cmd *cobra.Command, args []string) error { } log.Debug().Msgf("LocalCfg: %+v", LocalCfg) log.Debug().Msg("Initializing database tester") + dbs := []database.Database{} + for _, dbCfg := range LocalCfg.Databases { + dbs = append(dbs, database.NewPostgres(dbCfg)) + } tester := tester.NewPostgres(tester.Config{ - Databases: LocalCfg.Databases, + Databases: dbs, }) log.Info().Msg("Setup tester") err = tester.Setup(ctx) diff --git a/go.mod b/go.mod index 6b93f6a..e99c1dc 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.17.0 github.com/stretchr/testify v1.8.4 + go.uber.org/mock v0.3.0 ) require ( diff --git a/go.sum b/go.sum index 18673b9..574c2f1 100644 --- a/go.sum +++ b/go.sum @@ -208,6 +208,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/internal/service/service_test.go b/internal/service/service_test.go new file mode 100644 index 0000000..8884582 --- /dev/null +++ b/internal/service/service_test.go @@ -0,0 +1,125 @@ +package service + +import ( + "context" + "net/http/httptest" + "testing" + "time" + + "github.com/fbufler/database-monitor/internal/tester" + "github.com/gorilla/mux" + "github.com/stretchr/testify/assert" +) + +func TestNew(t *testing.T) { + type args struct { + config Config + results chan tester.Result + router *mux.Router + } + tests := []struct { + name string + args args + want Service + }{ + { + name: "New", + args: args{ + config: Config{ + Port: 8080, + InvalidationTime: 60, + }, + results: make(chan tester.Result), + router: mux.NewRouter(), + }, + want: &ServiceImpl{ + config: Config{Port: 8080, InvalidationTime: 60}, + results: make(chan tester.Result), + router: mux.NewRouter(), + resultsMap: make(map[string]tester.Result), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := New(tt.args.config, tt.args.results, tt.args.router) + if got == nil { + t.Errorf("New() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestServiceImplCollectResults(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + results := make(chan tester.Result) + s := New(Config{Port: 8080, InvalidationTime: 1}, results, mux.NewRouter()) + go s.(*ServiceImpl).collectResults(ctx) + results <- tester.Result{ + Database: "test", + Connectable: true, + Writable: true, + Readable: true, + ConnectionTime: 0, + Timestamp: time.Now(), + WriteTime: 0, + ReadTime: 0, + } + result, ok := s.(*ServiceImpl).resultsMap["test"] + assert.Equal(t, true, ok) + assert.Equal(t, "test", result.Database) + assert.Equal(t, true, result.Connectable) + assert.Equal(t, true, result.Writable) + assert.Equal(t, true, result.Readable) + assert.Equal(t, time.Duration(0), result.ConnectionTime) + assert.Equal(t, time.Duration(0), result.WriteTime) + assert.Equal(t, time.Duration(0), result.ReadTime) +} + +func TestServiceImplCollectResultsInvalidation(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + results := make(chan tester.Result) + s := New(Config{Port: 8080, InvalidationTime: 1}, results, mux.NewRouter()) + go s.(*ServiceImpl).collectResults(ctx) + results <- tester.Result{ + Database: "test", + Connectable: true, + Writable: true, + Readable: true, + ConnectionTime: 0, + Timestamp: time.Now().Add(-2 * time.Second), + WriteTime: 0, + ReadTime: 0, + } + _, ok := s.(*ServiceImpl).resultsMap["test"] + assert.Equal(t, false, ok) +} + +func TestRunResults(t *testing.T) { + router := mux.NewRouter() + results := make(chan tester.Result) + s := New(Config{Port: 8080, InvalidationTime: 1}, results, router) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go s.Run(ctx) + now := time.Now() + results <- tester.Result{ + Database: "test", + Connectable: true, + Writable: true, + Readable: true, + ConnectionTime: 0, + Timestamp: now, + WriteTime: 0, + ReadTime: 0, + } + time.Sleep(50 * time.Millisecond) + server := httptest.NewServer(router) + request := httptest.NewRequest("GET", server.URL+"/results", nil) + response := httptest.NewRecorder() + router.ServeHTTP(response, request) + assert.Equal(t, 200, response.Code) + assert.Equal(t, "{\"results\":{\"test\":{\"database\":\"test\",\"connectable\":true,\"connection_time\":0,\"writable\":true,\"write_time\":0,\"readable\":true,\"read_time\":0,\"timestamp\":\""+now.Format(time.RFC3339Nano)+"\"}}}\n", response.Body.String()) +} diff --git a/internal/tester/postgres.go b/internal/tester/postgres.go index b8b20b7..488d24c 100644 --- a/internal/tester/postgres.go +++ b/internal/tester/postgres.go @@ -21,84 +21,76 @@ func NewPostgres(config Config) Tester { } } +func (p *Postgres) Run(ctx context.Context) chan Result { + go p.run(ctx) + return p.results +} + func (p *Postgres) run(ctx context.Context) { log.Info().Msg("Starting postgres tester") - log.Debug().Msg("Initializing databases") - dbs := make([]database.Database, len(p.config.Databases)) - for i, cfg := range p.config.Databases { - dbs[i] = database.NewPostgres(cfg) - } log.Debug().Msg("Starting database tests") for { select { case <-ctx.Done(): log.Debug().Msg("Received termination signal") log.Debug().Msg("Closing databases") - for _, db := range dbs { + for _, db := range p.config.Databases { db.Close() } log.Debug().Msg("Closing results channel") close(p.results) return default: - for _, db := range dbs { - go func(db database.Database) { - result := Result{ - Database: db.Identifier(), - Connectable: false, - Writable: false, - Readable: false, - Timestamp: time.Now(), - } - connectionTime := time.Now() - err := db.Connect() - if err != nil { - log.Error().Msgf("connecting to %s: %s", result.Database, err) - p.results <- result - return - } - result.ConnectionTime = time.Since(connectionTime) - defer db.Close() - result.Connectable = true - readTime := time.Now() - readCtx, readCancel := context.WithTimeout(ctx, time.Duration(p.config.TestTimeout)*time.Second) - err = db.TestRead(readCtx) - readCancel() - if err != nil { - log.Error().Msgf("reading from %s: %s", result.Database, err) - p.results <- result - return - } - result.ReadTime = time.Since(readTime) - result.Readable = true - writeTime := time.Now() - writeCtx, writeCancel := context.WithTimeout(ctx, time.Duration(p.config.TestTimeout)*time.Second) - err = db.TestWrite(writeCtx) - writeCancel() - if err != nil { - log.Error().Msgf("writing to %s: %s", result.Database, err) - p.results <- result - return - } - result.WriteTime = time.Since(writeTime) - result.Writable = true - p.results <- result - }(db) + for _, db := range p.config.Databases { + go p.runDatabaseTest(db, ctx) } time.Sleep(time.Duration(p.config.TestInterval) * time.Second) } } } -func (p *Postgres) Run(ctx context.Context) chan Result { - go p.run(ctx) - return p.results +func (p *Postgres) runDatabaseTest(db database.Database, ctx context.Context) { + result := Result{ + Database: db.Identifier(), + Connectable: false, + Writable: false, + Readable: false, + Timestamp: time.Now(), + } + connectionTime := time.Now() + err := db.Connect() + if err != nil { + log.Error().Msgf("connecting to %s: %s", result.Database, err) + p.results <- result + return + } + result.ConnectionTime = time.Since(connectionTime) + defer db.Close() + result.Connectable = true + readTime := time.Now() + err = db.TestRead(ctx) + if err != nil { + log.Error().Msgf("reading from %s: %s", result.Database, err) + p.results <- result + return + } + result.ReadTime = time.Since(readTime) + result.Readable = true + writeTime := time.Now() + err = db.TestWrite(ctx) + if err != nil { + log.Error().Msgf("writing to %s: %s", result.Database, err) + p.results <- result + return + } + result.WriteTime = time.Since(writeTime) + result.Writable = true + p.results <- result } func (p *Postgres) Setup(ctx context.Context) error { var setupErrors []error - for _, cfg := range p.config.Databases { - db := database.NewPostgres(cfg) + for _, db := range p.config.Databases { err := db.SetupTestTable(ctx) if err != nil { setupErrors = append(setupErrors, err) diff --git a/internal/tester/postgres_test.go b/internal/tester/postgres_test.go new file mode 100644 index 0000000..dae1703 --- /dev/null +++ b/internal/tester/postgres_test.go @@ -0,0 +1,171 @@ +package tester + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/fbufler/database-monitor/pkg/database" + "github.com/stretchr/testify/assert" + gomock "go.uber.org/mock/gomock" +) + +func TestSetup(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockDatabase := database.NewMockDatabase(ctrl) + ctx := context.Background() + postgresTester := NewPostgres(Config{ + Databases: []database.Database{ + mockDatabase, + }, + }) + mockDatabase.EXPECT().SetupTestTable(ctx).Return(nil) + err := postgresTester.Setup(ctx) + if err != nil { + t.Errorf("Setup() error = %v", err) + } +} + +func TestSetupError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockDatabase := database.NewMockDatabase(ctrl) + ctx := context.Background() + postgresTester := NewPostgres(Config{ + Databases: []database.Database{ + mockDatabase, + }, + }) + setupError := errors.New("SetupTestTable error") + mockDatabase.EXPECT().SetupTestTable(ctx).Return(setupError) + err := postgresTester.Setup(ctx) + assert.EqualError(t, err, fmt.Errorf("setting up databases: %v", []error{setupError}).Error()) +} + +func TestRun(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockDatabase := database.NewMockDatabase(ctrl) + ctx, cancel := context.WithCancel(context.Background()) + postgresTester := NewPostgres(Config{ + TestTimeout: 1, + TestInterval: 1, + Databases: []database.Database{ + mockDatabase, + }, + }) + mockDatabase.EXPECT().Identifier().Return("test") + mockDatabase.EXPECT().Connect().Return(nil) + mockDatabase.EXPECT().TestRead(ctx).Return(nil) + mockDatabase.EXPECT().TestWrite(ctx).Return(nil) + mockDatabase.EXPECT().Close().Return(nil) + go postgresTester.Run(ctx) + result := <-postgresTester.(*Postgres).results + cancel() + assert.Equal(t, "test", result.Database) + assert.Equal(t, true, result.Connectable) + assert.Equal(t, true, result.Readable) + assert.Equal(t, true, result.Writable) +} + +func TestRunDatabaseTest(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockDatabase := database.NewMockDatabase(ctrl) + ctx, cancel := context.WithCancel(context.Background()) + postgresTester := NewPostgres(Config{ + TestTimeout: 1, + TestInterval: 1, + Databases: []database.Database{ + mockDatabase, + }, + }) + mockDatabase.EXPECT().Identifier().Return("test") + mockDatabase.EXPECT().Connect().Return(nil) + mockDatabase.EXPECT().TestRead(ctx).Return(nil) + mockDatabase.EXPECT().TestWrite(ctx).Return(nil) + mockDatabase.EXPECT().Close().Return(nil) + go postgresTester.(*Postgres).runDatabaseTest(mockDatabase, ctx) + result := <-postgresTester.(*Postgres).results + cancel() + assert.Equal(t, "test", result.Database) + assert.Equal(t, true, result.Connectable) + assert.Equal(t, true, result.Readable) + assert.Equal(t, true, result.Writable) +} + +func TestRunDatabaseTestConnectError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockDatabase := database.NewMockDatabase(ctrl) + ctx, cancel := context.WithCancel(context.Background()) + postgresTester := NewPostgres(Config{ + TestTimeout: 1, + TestInterval: 1, + Databases: []database.Database{ + mockDatabase, + }, + }) + mockDatabase.EXPECT().Identifier().Return("test") + mockDatabase.EXPECT().Connect().Return(errors.New("Connect error")) + go postgresTester.(*Postgres).runDatabaseTest(mockDatabase, ctx) + result := <-postgresTester.(*Postgres).results + cancel() + assert.Equal(t, "test", result.Database) + assert.Equal(t, false, result.Connectable) + assert.Equal(t, false, result.Readable) + assert.Equal(t, false, result.Writable) +} + +func TestRunDatabaseTestReadError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockDatabase := database.NewMockDatabase(ctrl) + ctx, cancel := context.WithCancel(context.Background()) + postgresTester := NewPostgres(Config{ + TestTimeout: 1, + TestInterval: 1, + Databases: []database.Database{ + mockDatabase, + }, + }) + mockDatabase.EXPECT().Identifier().Return("test") + mockDatabase.EXPECT().Connect().Return(nil) + mockDatabase.EXPECT().TestRead(ctx).Return(errors.New("Read error")) + mockDatabase.EXPECT().Close().Return(nil) + go postgresTester.(*Postgres).runDatabaseTest(mockDatabase, ctx) + result := <-postgresTester.(*Postgres).results + cancel() + assert.Equal(t, "test", result.Database) + assert.Equal(t, true, result.Connectable) + assert.Equal(t, false, result.Readable) + assert.Equal(t, false, result.Writable) +} + +func TestRunDatabaseTestWriteError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockDatabase := database.NewMockDatabase(ctrl) + ctx, cancel := context.WithCancel(context.Background()) + postgresTester := NewPostgres(Config{ + TestTimeout: 1, + TestInterval: 1, + Databases: []database.Database{ + mockDatabase, + }, + }) + mockDatabase.EXPECT().Identifier().Return("test") + mockDatabase.EXPECT().Connect().Return(nil) + mockDatabase.EXPECT().TestRead(ctx).Return(nil) + mockDatabase.EXPECT().TestWrite(ctx).Return(errors.New("Write error")) + mockDatabase.EXPECT().Close().Return(nil) + go postgresTester.(*Postgres).runDatabaseTest(mockDatabase, ctx) + result := <-postgresTester.(*Postgres).results + cancel() + assert.Equal(t, "test", result.Database) + assert.Equal(t, true, result.Connectable) + assert.Equal(t, true, result.Readable) + assert.Equal(t, false, result.Writable) +} diff --git a/internal/tester/tester.go b/internal/tester/tester.go index 3d02189..22c8db1 100644 --- a/internal/tester/tester.go +++ b/internal/tester/tester.go @@ -13,9 +13,9 @@ type Tester interface { } type Config struct { - Databases []database.Config `mapstructure:"databases"` - TestTimeout int `mapstructure:"test_timeout"` - TestInterval int `mapstructure:"test_interval"` + Databases []database.Database `mapstructure:"databases"` + TestTimeout int `mapstructure:"test_timeout"` + TestInterval int `mapstructure:"test_interval"` } type Result struct { diff --git a/pkg/database/database_mock.go b/pkg/database/database_mock.go new file mode 100644 index 0000000..5474cea --- /dev/null +++ b/pkg/database/database_mock.go @@ -0,0 +1,137 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/database/database.go +// +// Generated by this command: +// +// mockgen -source pkg/database/database.go +// +// Package mock_database is a generated GoMock package. +package database + +import ( + context "context" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockDatabase is a mock of Database interface. +type MockDatabase struct { + ctrl *gomock.Controller + recorder *MockDatabaseMockRecorder +} + +// MockDatabaseMockRecorder is the mock recorder for MockDatabase. +type MockDatabaseMockRecorder struct { + mock *MockDatabase +} + +// NewMockDatabase creates a new mock instance. +func NewMockDatabase(ctrl *gomock.Controller) *MockDatabase { + mock := &MockDatabase{ctrl: ctrl} + mock.recorder = &MockDatabaseMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDatabase) EXPECT() *MockDatabaseMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockDatabase) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockDatabaseMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockDatabase)(nil).Close)) +} + +// Connect mocks base method. +func (m *MockDatabase) Connect() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Connect") + ret0, _ := ret[0].(error) + return ret0 +} + +// Connect indicates an expected call of Connect. +func (mr *MockDatabaseMockRecorder) Connect() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockDatabase)(nil).Connect)) +} + +// Identifier mocks base method. +func (m *MockDatabase) Identifier() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Identifier") + ret0, _ := ret[0].(string) + return ret0 +} + +// Identifier indicates an expected call of Identifier. +func (mr *MockDatabaseMockRecorder) Identifier() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Identifier", reflect.TypeOf((*MockDatabase)(nil).Identifier)) +} + +// SetupTestTable mocks base method. +func (m *MockDatabase) SetupTestTable(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetupTestTable", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetupTestTable indicates an expected call of SetupTestTable. +func (mr *MockDatabaseMockRecorder) SetupTestTable(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetupTestTable", reflect.TypeOf((*MockDatabase)(nil).SetupTestTable), ctx) +} + +// Test mocks base method. +func (m *MockDatabase) Test(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Test", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Test indicates an expected call of Test. +func (mr *MockDatabaseMockRecorder) Test(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Test", reflect.TypeOf((*MockDatabase)(nil).Test), ctx) +} + +// TestRead mocks base method. +func (m *MockDatabase) TestRead(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TestRead", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// TestRead indicates an expected call of TestRead. +func (mr *MockDatabaseMockRecorder) TestRead(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TestRead", reflect.TypeOf((*MockDatabase)(nil).TestRead), ctx) +} + +// TestWrite mocks base method. +func (m *MockDatabase) TestWrite(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TestWrite", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// TestWrite indicates an expected call of TestWrite. +func (mr *MockDatabaseMockRecorder) TestWrite(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TestWrite", reflect.TypeOf((*MockDatabase)(nil).TestWrite), ctx) +}