Mocking & Spy
type Sender interface {
Send(from, recipient, subject, body string) error
}
func WelcomeUser(from string, sender Sender) error {
_ = sender.Send(
from,
"bob",
"bob i have news",
"i lied i dont actually",
)
return nil
}
We can implement a spy, which is a struct designed to record certain values. This struct gets passed in to the interface field.
type spySender struct {
sendCallCount int
from string
recipient string
subject string
body string
}
func (s *spySender) Send(from, recipient, subject, body string) error {
s.sendCallCount += 1
s.from = from
s.recipient = recipient
s.subject = subject
s.body = body
return nil
}
func TestWelcomeUser(t *testing.T) {
// Arrange
email := "ben@benlewisjones.com"
spy := spySender{
sendCallCount: 0,
recipient: "",
subject: "",
body: "",
}
// Act
err := WelcomeUser(email, &spy)
// Assert
if err != nil {
t.Errorf("An error was returned %q", err.Error())
}
if spy.sendCallCount != 1 {
t.Errorf("Expected to call send once, but it was called %v times", spy.sendCallCount)
}
expectedRecipient := "bob"
if spy.recipient != expectedRecipient {
t.Errorf("Expected recipient %q, but got %q", expectedRecipient, spy.recipient)
}
expectedSubject := "bob i have news"
if spy.subject != expectedSubject {
t.Errorf("Expected subject %q, but got %q", expectedSubject, spy.subject)
}
expectedBody := "i lied i dont actually"
if spy.body != expectedBody {
t.Errorf("Expected body %q, but got %q", expectedBody, spy.body)
}
}