Skip to content

Instantly share code, notes, and snippets.

@Ompluscator
Last active June 7, 2022 09:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ompluscator/7d97e4f00ccdb7f8255a19a2d44c1f41 to your computer and use it in GitHub Desktop.
Save Ompluscator/7d97e4f00ccdb7f8255a19a2d44c1f41 to your computer and use it in GitHub Desktop.
mocking
import (
//
// some imports
//
"github.com/stretchr/testify/assert"
)
func TestUser_HasAccess(t *testing.T) {
assert.False(t, User{}.HasAccess("admin"))
assert.True(t, User{
Roles; []string{"admin"}
}.HasAccess("admin"))
}
type UserDBRepository struct {
connection *sql.DB
}
func NewUserDBRepository(connection *sql.DB) *UserDBRepository {
return &UserDBRepository{
connection: connection,
}
}
func (r *UserDBRepository) FilterByLastname(ctx context.Context, lastname string) ([]User, error) {
var users []User
rows, err := r.connection.Query("SELECT * FROM users WHERE lastname = ?", lastname)
//
// do something with users
//
return users, nil
}
import (
//
// some imports
//
"github.com/DATA-DOG/go-sqlmock"
)
func TestUserDBRepository(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Error("expected not to have error")
}
mock.
ExpectQuery("SELECT * FROM users WHERE lastname = ?").
WithArgs("some last name").
WillReturnError(errors.New("error"))
repository := NewUserDBRepository(db)
users, err := repository.FilterByLastname(context.Background(), "some last name")
//
// do some checking for users and err
//
}
import (
//
// some imports
//
_ "github.com/mattn/go-sqlite3"
)
func getSqliteDBWithTestData() (*sql.DB, error) {
// read all from sqlite file
data, err := ioutil.ReadFile("test_data.sqlite")
if err != nil {
return nil, err
}
// create temporary file
tmpFile, err := ioutil.TempFile("", "db*.sqlite")
if err != nil {
return nil, err
}
// store test data into temporary file
_, err = tmpFile.Write(data)
if err != nil {
return nil, err
}
err = tmpFile.Close()
if err != nil {
return nil, err
}
// make connection to temporary file
db, err := sql.Open("sqlite3", tmpFile.Name())
if err != nil {
return nil, err
}
return db, nil
}
func TestUserDBRepository(t *testing.T) {
db, err := getSqliteDBWithTestData()
if err != nil {
t.Error("expected not to have error")
}
repository := NewUserDBRepository(db)
users, err := repository.FilterByLastname(context.Background(), "some last name")
//
// do some checking for users and err
//
}
type ConfigurationRepository struct {
//
// some fields
//
}
func (r *ConfigurationRepository) GetConfiguration() (map[string]string, error) {
config := map[string]string{}
data, err := ioutil.ReadFile("config.yml")
//
// do something with data
//
return config, nil
}
package ioutil
func ReadFile(filename string) ([]byte, error) {
//
// do something
//
}
type FileReaderFunc func(filename string) ([]byte, error)
type ConfigurationRepository struct {
fileReaderFunc FileReaderFunc
//
// some fields
//
}
func NewConfigurationRepository(fileReaderFunc FileReaderFunc) ConfigurationRepository{
return ConfigurationRepository{
fileReaderFunc: fileReaderFunc,
}
}
func (r *ConfigurationRepository) GetConfiguration() (map[string]string, error) {
config := map[string]string{}
data, err := r.fileReaderFunc("config.yml")
//
// do something with data
//
return config, nil
}
package main
func main() {
repository := NewConfigurationRepository(ioutil.ReadFile)
config, err := repository.GetConfiguration()
//
// do something with configuration
//
}
func TestGetConfiguration(t *testing.T) {
var readerFunc FileReaderFunc
// we want to have error from reader
readerFunc = func(filename string) ([]byte, error) {
return nil, errors.New("error")
}
repository := NewConfigurationRepository(readerFunc)
_, err := repository.GetConfiguration()
if err == nil {
t.Error("error is expected")
}
// we want to have concrete result from reader
readerFunc = func(filename string) ([]byte, error) {
return []byte("content"), nil
}
repository = NewConfigurationRepository(readerFunc)
_, err = repository.GetConfiguration()
if err != nil {
t.Error("error is not expected")
}
//
// do something with config
//
}
type FileReader interface {
ReadFile(filename string) ([]byte, error)
}
type ConfigurationRepository struct {
fileReader FileReader
//
// some fields
//
}
func NewConfigurationRepository(fileReader FileReader) *ConfigurationRepository {
return &ConfigurationRepository{
fileReader: fileReader,
}
}
func (r *ConfigurationRepository) GetConfiguration() (map[string]string, error) {
config := map[string]string{}
data, err := r.fileReader.ReadFile("config.yml")
//
// do something with data
//
return config, nil
}
type FileReaderFunc func(filename string) ([]byte, error)
func (f FileReaderFunc) ReadFile(filename string) ([]byte, error) {
return f(filename)
}
func main() {
repository := NewConfigurationRepository(FileReaderFunc(ioutil.ReadFile))
config, err := repository.GetConfiguration()
//
// do something with configuration
//
}
func TestGetConfiguration(t *testing.T) {
var readerFunc FileReaderFunc
// we want to have error from reader
readerFunc = func(filename string) ([]byte, error) {
return nil, errors.New("error")
}
repository := NewConfigurationRepository(readerFunc)
_, err := repository.GetConfiguration()
if err == nil {
t.Error("error is expected")
}
// we want to have concrete result from reader
readerFunc = func(filename string) ([]byte, error) {
return []byte("content"), nil
}
repository = NewConfigurationRepository(readerFunc)
config, err := repository.GetConfiguration()
if err != nil {
t.Error("error is not expected")
}
//
// do something with config
//
}
type UserDBRepository struct {
connection *sql.DB
}
func (r *UserDBRepository) FilterByLastname(ctx context.Context, lastname string) ([]User, error) {
var users []User
//
// do something with users
//
return users, nil
}
type AdminController struct {
repository *UserDBRepository
}
func (c *AdminController) FilterByLastname(ctx *gin.Context) {
lastname := ctx.Param("name")
c.repository.FilterByLastname(ctx, lastname)
//
// do something with users
//
}
type UserRepository interface {
GetByID(ctx context.Context, ID string) (*User, error)
GetByEmail(ctx context.Context, email string) (*User, error)
FilterByLastname(ctx context.Context, lastname string) ([]User, error)
Create(ctx context.Context, user User) (*User, error)
Update(ctx context.Context, user User) (*User, error)
Delete(ctx context.Context, user User) (*User, error)
}
type AdminController struct {
repository UserRepository
}
func (c *AdminController) FilterByLastname(ctx *gin.Context) {
lastname := ctx.Param("name")
c.repository.FilterByLastname(ctx, lastname)
//
// do something with users
//
}
type UserAPIRepository struct {
host string
}
func NewUserAPIRepository(host string) *UserAPIRepository {
return &UserAPIRepository{
host: host,
}
}
func (r *UserAPIRepository) FilterByLastname(ctx context.Context, lastname string) ([]User, error) {
var users []User
url := path.Join(r.host, "/users/", lastname)
response, err := http.Get(url)
//
// do somethinf with users
//
return users, nil
}
import (
//
// some imports
//
"net/http/httptest"
)
func TestUserAPIRepository(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/users/") {
var content string
//
// do something
//
io.WriteString(w, content)
return
}
http.NotFound(w, r)
}))
repository := NewUserAPIRepository(server.URL)
users, err := repository.FilterByLastname(context.Background(), "some last name")
//
// do some checking for users and err
//
}
type MockedUserRepository struct {
UserRepository
filterByLastnameFunc func(ctx context.Context, lastname string) ([]User, error)
}
func (r *MockedUserRepository) FilterByLastname(ctx context.Context, lastname string) ([]User, error) {
return r.filterByLastnameFunc(ctx, lastname)
}
func TestAdminController(t *testing.T) {
var gCtx *gin.Context
//
// setup context
//
repository := &MockedUserRepository{}
repository.filterByLastnameFunc = func(ctx context.Context, lastname string) ([]User, error) {
if ctx != gCtx {
t.Error("expected other context")
}
if lastname != "some last name" {
t.Error("expected other lastname")
}
return nil, errors.New("error")
}
controller := NewAdminController(repository)
controller.FilterByLastname(gCtx)
//
// do some checking for ctx
//
}
import (
//
// some imports
//
"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
)
type SQSReceiver struct {
sqsAPI sqsiface.SQSAPI
}
func (r *SQSReceiver) Run() {
//
// wait for SQS message
//
}
type MockedSQSAPI struct {
sqsiface.SQSAPI
sendMessageFunc func(input *sqs.SendMessageInput) (*sqs.SendMessageOutput, error)
}
func (m *MockedSQSAPI) SendMessage(input *sqs.SendMessageInput) (*sqs.SendMessageOutput, error) {
return m.sendMessageFunc(input)
}
func TestSQSReceiver(t *testing.T) {
//
// setup context
//
sqsAPI := &MockedSQSAPI{}
sqsAPI.sendMessageFunc = func(input *sqs.SendMessageInput) (*sqs.SendMessageOutput, error) {
if input.MessageBody == nil || *input.MessageBody != "content" {
t.Error("expected other message")
}
return nil, errors.New("error")
}
receiver := &SQSReceiver{
sqsAPI: sqsAPI,
}
receiver.Run()
//
// do some checking for ctx
//
}
type User struct {
//
// some fields
//
}
type UserRepository interface {
GetByID(ctx context.Context, ID string) (*User, error)
GetByEmail(ctx context.Context, email string) (*User, error)
FilterByLastname(ctx context.Context, lastname string) ([]User, error)
Create(ctx context.Context, user User) (*User, error)
Update(ctx context.Context, user User) (*User, error)
Delete(ctx context.Context, user User) (*User, error)
}
type AdminController struct {
repository UserRepository
}
func NewAdminController(repository UserRepository) *AdminController {
return &AdminController{
repository: repository,
}
}
func (c *AdminController) FilterByLastname(ctx *gin.Context) {
lastname := ctx.Param("name")
c.repository.FilterByLastname(ctx, lastname)
//
// do something with users
//
}
func main() {
var repository UserRepository
//
// initialize repository
//
controller := NewAdminController(repository)
router := gin.Default()
router.GET("/users/:lastname", controller.FilterByLastname)
//
// do something with router
//
}
// Code generated by mockery v1.0.0. DO NOT EDIT.
package mocks
import (
//
// some imports
//
mock "github.com/stretchr/testify/mock"
)
// UserRepository is an autogenerated mock type for the UserRepository type
type UserRepository struct {
mock.Mock
}
// Create provides a mock function with given fields: ctx, _a1
func (_m *UserRepository) Create(ctx context.Context, _a1 user.User) (*user.User, error) {
ret := _m.Called(ctx, _a1)
var r0 *user.User
if rf, ok := ret.Get(0).(func(context.Context, user.User) *user.User); ok {
r0 = rf(ctx, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*user.User)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, user.User) error); ok {
r1 = rf(ctx, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// and so on....
package user
//go:generate go run github.com/vektra/mockery/cmd/mockery -all -case=underscore
func TestAdminController(t *testing.T) {
var ctx *gin.Context
//
// setup context
//
repository := &mocks.UserRepository{}
repository.
On("FilterByLastname", ctx, "some last name").
Return(nil, errors.New("some error")).
Once()
controller := NewAdminController(repository)
controller.FilterByLastname(ctx)
//
// do some checking for ctx
//
}
// Code generated by mockery v1.0.0. DO NOT EDIT.
package mocks
import (
context "context"
mock "github.com/stretchr/testify/mock"
user "thinksurance.de/test/fc"
)
// UserRepository is an autogenerated mock type for the UserRepository type
type UserRepository struct {
mock.Mock
}
// Create provides a mock function with given fields: ctx, _a1
func (_m *UserRepository) Create(ctx context.Context, _a1 user.User) (*user.User, error) {
ret := _m.Called(ctx, _a1)
var r0 *user.User
if rf, ok := ret.Get(0).(func(context.Context, user.User) *user.User); ok {
r0 = rf(ctx, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*user.User)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, user.User) error); ok {
r1 = rf(ctx, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// and so on....
func TestAdminController(t *testing.T) {
var ctx *gin.Context
//
// setup context
//
repository := &mocks.UserRepository{}
repository.
On("FilterByLastname", ctx, "some last name").
Return(nil, errors.New("some error")).
Once()
controller := NewAdminController(repository)
controller.FilterByLastname(ctx)
//
// do some checking for ctx
//
}
import (
//
// some imports
//
"github.com/stretchr/testify/suite"
)
type AdminControllerTestSuite struct {
suite.Suite
controller *AdminController
repository *mocks.UserRepository
ctx *gin.Context
}
func TestAdminControllerTestSuite(t *testing.T) {
suite.Run(t, &AdminControllerTestSuite{})
}
func (s *AdminControllerTestSuite) SetupSuite() {
s.ctx = &gin.Context()
}
func (s *AdminControllerTestSuite) SetupTest() {
s.repository = &mocks.UserRepository{}
s.controller = NewAdminController(s.repository)
}
func (s *AdminControllerTestSuite) TearDownTest() {
s.repository.AssertExpectations(s.T())
}
func (s *AdminControllerTestSuite) TestFind_ProfessionError() {
s.repository.
On("FilterByLastname", s.ctx, "some last name").
Return(nil, errors.New("some error")).
Once()
s.controller.FilterByLastname(s.ctx)
//
// do some checking for s.ctx
//
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment