Skip to content

Commit

Permalink
Learned about mocking & implemented a countdowner
Browse files Browse the repository at this point in the history
  • Loading branch information
vedicpanda committed May 31, 2023
1 parent 919c637 commit ca9f5aa
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
76 changes: 76 additions & 0 deletions Mocking/countdown.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"fmt"
"io"
"os"
"time"
)

type Sleeper interface {
Sleep()
}

type SpySleeper struct {
Calls int
}

func (s *SpySleeper) Sleep() {
s.Calls++
}

type DefaultSleeper struct{}

func (d *DefaultSleeper) Sleep() {
time.Sleep(1 * time.Second)
}

const write = "write"
const sleep = "sleep"

type SpyCountdownOperations struct {
Calls []string
}

func (s *SpyCountdownOperations) Sleep() {
s.Calls = append(s.Calls, sleep)
}

func (s *SpyCountdownOperations) Write(p []byte) (n int, err error) {
s.Calls = append(s.Calls, write)
return
}

type ConfigurableSleeper struct {
duration time.Duration
sleep func(time.Duration)
}

type SpyTime struct {
durationSlept time.Duration
}

func (s *SpyTime) Sleep(duration time.Duration) {
s.durationSlept = duration
}

func (c *ConfigurableSleeper) Sleep() {
c.sleep(c.duration)
}

const finalWord = "Go!"
const countdownStart = 3

func Countdown(out io.Writer, sleeper Sleeper) {
for i := countdownStart; i > 0; i-- {
fmt.Fprintln(out, i)
sleeper.Sleep()
}

fmt.Fprint(out, finalWord)
}

func main() {
sleeper := &ConfigurableSleeper{1 * time.Second, time.Sleep}
Countdown(os.Stdout, sleeper)
}
57 changes: 57 additions & 0 deletions Mocking/countdown_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package main

import (
"bytes"
"reflect"
"testing"
"time"
)

func TestCountdown(t *testing.T) {

t.Run("prints 3 to Go!", func(t *testing.T) {
buffer := &bytes.Buffer{}
Countdown(buffer, &SpyCountdownOperations{})

got := buffer.String()
want := `3
2
1
Go!`

if got != want {
t.Errorf("got %q want %q", got, want)
}
})

t.Run("sleep before every print", func(t *testing.T) {
spySleepPrinter := &SpyCountdownOperations{}
Countdown(spySleepPrinter, spySleepPrinter)

want := []string{
write,
sleep,
write,
sleep,
write,
sleep,
write,
}

if !reflect.DeepEqual(want, spySleepPrinter.Calls) {
t.Errorf("wanted calls %v got %v", want, spySleepPrinter.Calls)
}
})
}

func TestConfigurableSleeper(t *testing.T) {
sleepTime := 5 * time.Second

spyTime := &SpyTime{}
sleeper := ConfigurableSleeper{sleepTime, spyTime.Sleep}
sleeper.Sleep()

if spyTime.durationSlept != sleepTime {
t.Errorf("should have slept for %v but slept for %v", sleepTime, spyTime.durationSlept)
}
}

0 comments on commit ca9f5aa

Please sign in to comment.