The obstacle was seeing it as an action on a form. Thinking instead on information that needs to be introduced and sent made the names flow much better.
This is the resulting class:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class IntroducedInformation | |
{ | |
private $emailSender; | |
private $redirection; | |
private $formEmailComposer; | |
private $form; | |
function __construct( | |
Form $form, | |
EmailSender $emailSender, | |
Redirection $redirection, | |
FormEmailComposer $formEmailComposer | |
) { | |
$this->emailSender = $emailSender; | |
$this->redirection = $redirection; | |
$this->formEmailComposer = $formEmailComposer; | |
$this->form = $form; | |
} | |
public function sendByEmailAndRedirect() | |
{ | |
if ($this->form->isNotFilled()) { | |
$this->redirection->backToInitialPage(); | |
return; | |
} | |
$email = $this->createEmail(); | |
$sendingSucceeded = $this->send($email); | |
$this->redirect($sendingSucceeded); | |
} | |
private function redirect($sendingSucceeded) | |
{ | |
if ($sendingSucceeded) { | |
$this->redirection->toSuccessPage(); | |
} else { | |
$this->redirection->toFailPage(); | |
} | |
} | |
private function createEmail() | |
{ | |
return | |
$this->formEmailComposer | |
->composeEmailFrom($this->form); | |
} | |
private function send(Email $email) | |
{ | |
return $this->emailSender->send($email); | |
} | |
} |
and these are its tests:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class IntroducedInformationTest extends PHPUnit_Framework_TestCase | |
{ | |
private $form; | |
private $redirection; | |
private $emailSender; | |
private $introducedInformation; | |
private $formEmailComposer; | |
private $email; | |
function setUp() | |
{ | |
$this->redirection = Phake::mock('Redirection'); | |
$this->email = new Email("from", "to", "subject", "message"); | |
$this->form = Phake::mock('Form'); | |
$this->emailSender = Phake::mock('EmailSender'); | |
$this->formEmailComposer = Phake::mock('FormEmailComposer'); | |
$this->introducedInformation = | |
new IntroducedInformation( | |
$this->form, | |
$this->emailSender, | |
$this->redirection, | |
$this->formEmailComposer | |
); | |
} | |
function testRedirectionBackToFormPage() | |
{ | |
$this->whenFormNotFilled(); | |
$this->introducedInformation->sendByEmailAndRedirect(); | |
Phake::verify($this->redirection) | |
->backToInitialPage(); | |
} | |
function testEmailComposition() | |
{ | |
$this->whenFormFilledWithWhateverFields(); | |
$this->andEmailGetsComposed(); | |
$this->introducedInformation->sendByEmailAndRedirect(); | |
Phake::verify($this->formEmailComposer) | |
->composeEmailFrom($this->form); | |
} | |
function testEmailSending() | |
{ | |
$this->whenFormFilledWithWhateverFields(); | |
$this->andEmailGetsComposed(); | |
$this->introducedInformation->sendByEmailAndRedirect(); | |
Phake::verify($this->emailSender) | |
->send($this->email); | |
} | |
function testRedirectionToSuccesPage() | |
{ | |
$this->whenFormFilledWithWhateverFields(); | |
$this->andEmailGetsComposed(); | |
$this->andIsSentSuccessfully(); | |
$this->introducedInformation->sendByEmailAndRedirect(); | |
Phake::verify($this->redirection)->toSuccessPage(); | |
} | |
function testRedirectionToFailPage() | |
{ | |
$this->whenFormFilledWithWhateverFields(); | |
$this->andEmailGetsComposed(); | |
$this->butIsNotSentSuccessfully(); | |
$this->introducedInformation->sendByEmailAndRedirect(); | |
Phake::verify($this->redirection)->toFailPage(); | |
} | |
private function whenFormFilledWithWhateverFields() | |
{ | |
Phake::when($this->form) | |
->isNotFilled() | |
->thenReturn(false); | |
} | |
private function whenFormNotFilled() | |
{ | |
Phake::when($this->form) | |
->isNotFilled() | |
->thenReturn(true); | |
} | |
private function andIsSentSuccessfully() | |
{ | |
Phake::when($this->emailSender) | |
->send($this->email) | |
->thenReturn(true); | |
} | |
private function butIsNotSentSuccessfully() | |
{ | |
Phake::when($this->emailSender) | |
->send($this->email) | |
->thenReturn(false); | |
} | |
private function andEmailGetsComposed() | |
{ | |
Phake::when($this->formEmailComposer) | |
->composeEmailFrom($this->form) | |
->thenReturn($this->email); | |
} | |
} |
Finally, this is how it's used now:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$info = | |
IntroducedInfoBuilder::aNewIntroducedInformation() | |
->onPage("empresas") | |
->toBeSentTo("xxx@ppp.es") | |
->build(); | |
$info->sendByEmailAndRedirect(); |
I'm much happier with the naming now.
The tests are still fragile, but by using helpers in the tests the amount of places where the mocks are used gets reduced.