rogervinas / tests-everywhere
🤠 Tests, Tests Everywhere!
Go testing this simple Hello World with Standard library
Show me the code
Implementation
- Create
HelloMessage
interface andHelloWorldMessage
implementation in HelloMessage.go:
type HelloMessage interface {
Text() string
}
type HelloWorldMessage struct{}
func (message *HelloWorldMessage) Text() string {
return "Hello World!"
}
Creating it as an interface will allow us to mock it for testing.
- Same way create
HelloConsole
interface andHelloSystemConsole
implementation in HelloConsole.go:
type HelloConsole interface {
Print(text string)
}
type HelloSystemConsole struct{}
func (console *HelloSystemConsole) Print(text string) {
fmt.Println(text)
}
- Create
HelloApp
class in HelloApp.go:
type HelloApp struct {
message HelloMessage
console HelloConsole
}
func (app *HelloApp) PrintHello() {
app.console.Print(app.message.Text())
}
- Create main function in Main.go that wraps it all together:
func main() {
message := HelloWorldMessage{}
console := HelloSystemConsole{}
app := HelloApp{&message, &console}
app.PrintHello()
}
Test
Following Standard library > testing guide ...
- Test
HelloMessage
in HelloMessage_test.go:
func TestShouldReturnHelloWorld(t *testing.T) {
messageText := "Hello World!"
message := HelloWorldMessage{}
if message.Text() != messageText {
t.Fatalf("Expected %s but got %s", messageText, message.Text())
}
}
- Test
HelloApp
in HelloApp_test.go:
// 2.1 Define a HelloMessageMock struct that ...
type HelloMessageMock struct {
text string
}
// ... fullfils HelloMessage interface
func (message *HelloMessageMock) Text() string {
return message.text
}
// 2.2 Define a HelloConsoleMock that ...
type HelloConsoleMock struct {
Calls int
Text string
}
// ... fullfills HelloConsole interface
func (console *HelloConsoleMock) Print(text string) {
console.Calls++
console.Text = text
}
func TestShouldReturnPrintHelloMessage(t *testing.T) {
messageText := "Hello Test!"
// 2.3 Create a HelloMessageMock
// that will return "Hello Test!"
message := HelloMessageMock{messageText}
// 2.4 Create a HelloConsoleMock
// that will capture its calls
console := HelloConsoleMock{}
// 2.5 Create a HelloApp, the one we want to test, passing the mocks
app := HelloApp{&message, &console}
// 2.6 Execute the method we want to test
app.PrintHello()
// 2.7 Assert HelloConsoleMock has been called once
if console.Calls != 1 {
t.Fatalf("HelloConsole expected calls 1 but got %d", console.Calls)
}
// 2.8 Assert HelloConsoleMock has been called with "Hello Test!"
if console.Text != messageText {
t.Fatalf("HelloConsole expected text %s but got %s", messageText, console.Text)
}
}
- Test output should look like:
=== RUN TestShouldReturnPrintHelloMessage
--- PASS: TestShouldReturnPrintHelloMessage (0.00s)
=== RUN TestShouldReturnHelloWorld
--- PASS: TestShouldReturnHelloWorld (0.00s)
PASS
ok org.hello/main 0.412s
Happy Testing! 💙
Top comments (0)