golang

GoLang Mock Examples

The Golang mock examples refer to code examples that demonstrate the usage of mocking techniques in Golang. Mocking is a testing approach that uses mock implementations to substitute the dependencies, allowing you to control the behavior of those dependencies during testing.

In software development, the applications often have dependencies on external systems, databases, APIs, or other complex components. When writing unit tests for a specific piece of code, it is desirable to isolate that code and test it independently from its dependencies. Mocking helps achieve this isolation by providing fake implementations of those dependencies, allowing you to simulate specific scenarios and control the behavior of the dependencies.

Example 1: Mocking an Interface Method

Mocking an interface method refers to creating a fake or mock implementation of an interface method in order to isolate and test the behavior of a dependent component.

Interfaces in Go specify a collection of method signatures. Any method declarations in an interface that a struct type implements must have implementations available.

Mocking an interface method involves creating a separate implementation of the interface that mimics the behavior of the original implementation which allows you to control the output or behavior for testing purposes.

package main

import (

  "fmt"

  "testing"

)

type MyInterface interface {

  MyMethod() string

}

type MyStruct struct{}

func (m *MyStruct) MyMethod() string {

  return "Hello, World!"

}

type MyMockStruct struct{}

func (m *MyMockStruct) MyMethod() string {

vreturn "Mocked Method"

}

func main() {

  TestMyMethod(&testing.T{})

}

func TestMyMethod(t *testing.T) {

  var myInterface MyInterface

  myStruct := &MyStruct{}

  myInterface = myStruct

  result := myInterface.MyMethod()

  fmt.Println(result)

  myMockStruct := &MyMockStruct{}

  myInterface = myMockStruct

  result = myInterface.MyMethod()

  fmt.Println(result)

}

Let’s go through the code step by step and explain in detail what each part does:

The code begins with the package declaration, the “package main”, which indicates that this is the main package of the program. It is followed by the “import” statements where the “fmt” package is imported for standard input/output operations, and the testing package is imported for testing-related functionality.

We define an interface named “MyInterface” with a single method which is MyMethod(). This interface provides a contract that any type that implements “MyInterface” must have a method with the same signature. After that, the code defines a struct called “MyStruct” which represents a concrete implementation of the “MyInterface” interface.

We define a method named “MyMethod” on the “MyStruct” type. The signature of this function is identical to that of the “MyMethod” method that is declared in the “MyInterface” interface. The method implementation returns the “Hello, World!” string.

Next, the code defines another struct called “MyMockStruct”. This struct represents a mock implementation of the “MyInterface” interface. Similar to “MyStruct”, we define a method named “MyMethod” on the “MyMockStruct” type. This method also has the same signature as the “MyMethod” method that is declared in the “MyInterface” interface. The implementation of this method returns the “Mocked Method” string.

In the main function, we call the “TestMyMethod” function, passing the “&testing.T{}” as an argument. This executes the “TestMyMethod” test function.

The “TestMyMethod” function is a test function that demonstrates the use of the interface and the implementations of “MyMethod”. Inside the function, we declare the “myInterface” interface variable of the “MyInterface” type. We then create an instance of “MyStruct” called “myStruct” using “&MyStruct{}” and assign it to “myInterface”. This is possible because “MyStruct” implements the “MyInterface” interface.

Next, we call the “MyMethod” method via the interface by invoking myInterface.MyMethod(). Since “myInterface” holds an instance of “MyStruct”, it executes the implementation of “MyMethod” in “MyStruct” which returns “Hello, World. The fmt.Println(result) command prints this string to the console.

After that, we create an instance of “MyMockStruct” called “myMockStruct” using the “&MyMockStruct{}”. We then assign “myMockStruct” to “myInterface”, replacing the previous instance. Finally, we call the myInterface.MyMethod() again. This time, the implementation in “MyMockStruct” is executed, returning the “Mocked Method”.

The outcome that is displayed on the console is provided in the following:

Example 2: Mocking a Struct Method

Golang mock examples refer to code examples that demonstrate the usage of mocking techniques in Golang. In Go, it is possible to mock the struct methods using interfaces.

Here’s a simple example to illustrate the process:

package main
import "fmt"
type SomeInterface interface {
    SomeMethod() int
}
type SomeStruct struct{}
func (s SomeStruct) SomeMethod() int { 
    return 42
}
type SomeMock struct{}
func (m SomeMock) SomeMethod() int {   
    return 100
}
func main() {
    var obj SomeInterface  
    obj = SomeStruct{}
    result := obj.SomeMethod()
    fmt.Println(result)
    obj = SomeMock{}
    result = obj.SomeMethod()
    fmt.Println(result)
}

The necessary packages are imported in the standard import section. In this case, we import “fmt” to print the output and “testing” for testing-related functionality.

Next, an interface named “SomeInterface” is declared. This interface has a single method which is SomeMethod() that returns an integer. After that, a struct named “SomeStruct” is defined. This struct doesn’t have any fields but implements the SomeMethod() method that is defined in the “SomeInterface” interface. The SomeMethod() method is implemented for the “SomeStruct” struct. In this implementation, it returns the value of 42. This represents the actual behavior of the method.

Another struct named “SomeMock” is defined. This struct is used as a mock implementation for testing purposes. The SomeMethod() method is implemented for the “SomeMock” struct. In this implementation, it returns the value of 100. This represents the mock behavior of the method.

Inside the main() function, the “obj” variable of “SomeInterface” type is declared. This variable is used to hold the instances of the interface. The actual struct, SomeStruct{}, is assigned to the “obj” variable. This means that “obj” now holds an instance of “SomeStruct” but is accessed through the “SomeInterface” type. This demonstrates the flexibility of the Go interfaces.

The result is allocated to the “result” variable once the SomeMethod() method on the “obj” variable is called. In this case, since “obj” holds an instance of “SomeStruct”, the actual implementation of SomeMethod() in “SomeStruct” is executed, returning the value of 42. The fmt.Println(result) command outputs the value of the result to the terminal. In this case, it outputs 42.

Next, the “obj” variable is assigned with the SomeMock{} mock struct. This means that “obj” now holds an instance of “SomeMock” but is still accessed through the “SomeInterface” type. The “obj” variable is used to invoke the SomeMethod() function once again, and the result is thereafter assigned to the result variable. This time, since “obj” holds an instance of “SomeMock”, the mock implementation of SomeMethod() in “SomeMock” is executed which returns the value of 100. The value of the result is printed to the console by the fmt.Println(result) command. In this case, it outputs 100.

The program execution ends, and the program terminates.

 

Conclusion

Mocking is a very handy technique in Golang. This post explores two mocking techniques provided by Golang. The first method involves mocking the interface. While the second method performed the struct mocking, which also needs to use the interface, in GoLang. Both the illustrations are implementable and are explained in detail. Also, the outputs of the codes are provided.

About the author

Kalsoom Bibi

Hello, I am a freelance writer and usually write for Linux and other technology related content