Mocking the Kubernetes client in Go for Unit Testing
Yes, we can mimic K8s Client!
Writing unit tests is always a pain for developers. The main reason for this is that, usually, the unit tests (functional unit tests) must not use any physical components/running instances of the application. For example, the unit tests for an SDK of an API should not have any running instance of the API. Which is why, mocking the application instances becomes critical and that is the trick too!
In this article, we shall understand how to mock the Kubernetes client using the fake clientset of client-go
package. Lets’s begin!
Create a package called client
and a file called client.go
which defines a struct called Client
which holds the Kubernetes Clientset
.
Kubernetes Clientset
- contains the clients for groups.
- is the struct used to implement the Kubernetes interface called
Interface
. NewForConfig()
is the constructor of the KubernetesInterface
interface that returns the Clientset object.
Moving on, let’s define a public struct called Client
in client.go
Create a method called CreatePod
that is called upon the Client
struct to create pods in a given namespace
as shown in the same client.go
file
The complete client.go
file looks like this
Now, let us implement a main.go
to consume the above CreatePod
method. For this, we need to
- build the
clientset
- load the
Client
struct
- define a
pod
resource object
- invoke the
CreatePod
call upon theclient
object
The complete main.go
file looks like this
When we run this main.go
file against a running cluster, we end up creating a pod called test-pod
in the default
namespace.
Now, let us write a unit test for the same using the Go’s testing
package. Here, inorder to create the Kubernetes Clientset
, we use the NewSimpleClientSet()
constructor from the fake
package of client-go/kubernetes
package instead of NewForConfig()
constructor.
What is the difference?
NewForConfig()
constructor returns the actual ClientSet
that has the clients for every Kubernetes groups and operates upon an actual cluster. Whereas, NewSimpleClientSet()
constructor returns clientset that will respond with the provided objects. It’s backed by a very simple object tracker that processes creates, updates and deletions as-is, without applying any validations and/or defaults.
What is important to note here is that the Clientset
of the fake package also implements the Kubernetes Interface. Meant to be embedded into a struct to get a default implementation. This makes faking out just the method you want to test easier.
Our main_test.go
would like this
Now, if we run this test file using go test
command, we will successfully execute the CreatePod()
method even without running this against any running K8s cluster & by bypassing the Get()
call by mimicing it to return the same object as sent as a parameter to it. Output will be something as shown
go test
I0520 00:02:03.789351 23893 pod.go:23] Pod test-pod is succesfully created
PASS
ok github.com/kubernetes-sdk-for-go-101 0.681s
You can keep this article as reference and build upon this, a test framework or a unit test package for your applications employing Kubernetes client-go
. I hope this was helpful. If you have any doubts, concerns or comments, then please feel free to leave them below.
Thanks & regards,
Samarth Deyagond (aka Teddy Winters)