pattern for making other "tricky external systems" testable: The Email::send() method makes uses of a static object, Email::$mailer , to do the dirty work of calling mail(). The default mailer is an object of type Mailer , which performs a normal send. Email::set_mailer() can be called to load in a new mailer object. SapphireTest::setUp() method calls Email::set_mailer(new TestMailer()) to replace the default mailer with a TestMailer object. This replacement mailer doesn't actually do anything when it is asked to send an email; it just records the details of the email in an internal field that can be searched with TestMailer::findEmails() . SapphireTest::assertEmailSent() calls TestMailer::findEmails() to see if a mail-send was requested by the application. Comments Comment policy: Please use comments for tips and corrections about the described functionality. Comments are moderated, we reserve the right to remove comments that are inappropriate or are no longer relevant. Use the Silverstripe Forum to ask questions.