How to mock? Go Way.

System

Example System and Integration.
  1. “Our Service” that we own and build.
  2. “Third-party service or library” that interacts with some database and we use the functionality of it in our service.

Third-party Library Code

Service

// RegisterUser if the user is not registered before
func RegisterUser(user User) error {
if userdb.UserExist(user.Email) {
return fmt.Errorf("email '%s' already registered",
user.Email)
}
// ...code for registering the user...
log.Println(user)
return nil
}

Mocks

  1. Mock objects meet the interface requirements.
// registrationPreChecker validates if user is allowed to register.
type registrationPreChecker interface {
userExists(string) bool
}
type regPreCheck struct {}func (r regPreCheck) userExists(email string) bool {
return userdb.UserExist(email)
}
var regPreCond registrationPreChecker

func init() {
regPreCond = regPreCheck{}
}
// check if user is already registered
found := regPreCond.userExist(user.Email)

Writing mocks

type preCheckMock struct{}

func (u preCheckMock) userExists(email string) bool {
return userExistsMock(email)
}
regPreCond = preCheckMock{}
func TestRegisterUser(t *testing.T) {
user := User{
Name: "Ankur Anand",
Email: "anand@example.com",
UserName: "anand",
}

regPreCond = preCheckMock{}
userExistsMock = func(email string) bool {
return false
}

err := RegisterUser(user)
if err != nil {
t.Fatal(err)
}

userExistsMock = func(email string) bool {
return true
}
err = RegisterUser(user)
if err == nil {
t.Error("Expected Register User to throw and error got nil")
}
}

But we are done yet!

func NewRegistrationPreChecker() RegistrationPreChecker {
return regPreCheck{}
}

// RegisterUser will register a User if only User has not been previously
// registered.
func
RegisterUser(user User, regPreCond RegistrationPreChecker) error {
// check if user is already registered
found := regPreCond.userExists(user.Email)
if found {
return fmt.Errorf("email '%s' already registered", user.Email)
}
// carry business logic and Register the user in the system
log.Println(user)
return nil
}
func TestRegisterUser(t *testing.T) {
user := User{
Name: "Ankur Anand",
Email: "anand@example.com",
UserName: "anand",
}

regPreCond := preCheckMock{}
userExistsMock = func(email string) bool {
return false
}

err := RegisterUser(user, regPreCond)
if err != nil {
t.Fatal(err)
}

userExistsMock = func(email string) bool {
return true
}
err = RegisterUser(user, regPreCond)
if err == nil {
t.Error("Expected Register User to throw and error got nil")
}
}

Conclusion

Let’s stay in touch:

  • ❤️ Do you want to help? Please clap and share the article. Let other people also learn from this article.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store