Introduction
In the previous articles, we
- Created a CLI application using Go and Cobra
- Restructured the code to be extensible, maintainable, and unit testable
In this article, we will write unit tests for our CLI application. Let's get started.
Unit Test- Root Command
In the cmd/greeter directory, create a new file called root_test.go. As the name implies, this file will hold the unit test for the root command. Add the following test to the file.
// cmd/greeter/root_test.go
package greeter_test
import (
"bytes"
"greeter/cmd/greeter"
"testing"
)
func TestRootCmd_Execute(t *testing.T) {
// Create the root command
cmd := greeter.RootCommand()
// Redirect stdout to a buffer to capture the output
var stdout bytes.Buffer
cmd.SetOut(&stdout)
// Execute the root command
err := cmd.Execute()
// Check for any execution error
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// Check the output
expectedOutput := "Welcome to Greeter!"
if stdout.String() != expectedOutput {
t.Errorf("Expected output: %q, but got: %q", expectedOutput, stdout.String())
}
}
I have added inline code comments so that the code is self-explanatory.
Unit Test - Greet Command
Next, we create another file called greet_test.go into the cmd/greeter directory. As the name implies, this file will hold the unit test for the greet command. Add the following test to the file.
// cmd/greeter/greet_test.go
package greeter_test
import (
"bytes"
"greeter/cmd/greeter"
"testing"
)
func TestGreetCmd_Execute(t *testing.T) {
// Create the greet command
cmd := greeter.GreetCommand()
// Redirect stdout to a buffer to capture the output
var stdout bytes.Buffer
cmd.SetOut(&stdout)
// Set the arguments
cmd.SetArgs([]string{"John"})
// Execute the greet command with an argument
err := cmd.Execute()
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// Check the output
expectedOutput := "Hello, John!\n"
if stdout.String() != expectedOutput {
t.Errorf("Expected output: %q, but got: %q", expectedOutput, stdout.String())
}
}
As earlier, I have added inline code comments so that the code is self-explanatory.
To run the tests, head over to the terminal, execute the following command, and see a similar output.
~/workspace/greeter via 🐹 v1.20.2 at ☸️ kind-kind
➜ go test ./... -v
? greeter/cmd [no test files]
=== RUN TestGreetCmd_Execute
--- PASS: TestGreetCmd_Execute (0.00s)
=== RUN TestRootCmd_Execute
--- PASS: TestRootCmd_Execute (0.00s)
PASS
ok greeter/cmd/greeter 0.160s
Conclusion
We have successfully added initial unit tests for both- root and greet commands of our CLI application. As your application grows, it becomes even more essential to have unit tests in place to test if the business logic is working as expected. Next, we will see how to add required and optional flags to a command.