I should never have believed them. Luckily a colleague of mine didn't. In fact it turns out it's strikingly easy so I'd like to share it with you.
Here's an example of a how to unit test a standard action “executeHelloWorld” and an ajax action “executeGoodEvening”. It takes two simple lines in the setUp to prepare instantiation of the action.
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 ActionTest extends PHPUnit_Framework_TestCase { | |
protected $action; | |
public function setUp() { | |
$debug = true; | |
$configuration = ProjectConfiguration:: | |
getApplicationConfiguration('frontend', 'test', $debug); | |
$sfContext = sfContext::createInstance($configuration); | |
$this->action = new myActions($sfContext, null, null); | |
} | |
/** @test */ | |
public function iCanTestNormalActionsThroughTheVarHolder() { | |
$request = new sfWebRequest(new sfEventDispatcher(), | |
array('name' => 'Brian')); | |
$this->action->executeHelloWorld($request); | |
assertThat($this->action->getVar('helloMessage'), | |
equalTo('Hello Brian')); | |
} | |
/** @test */ | |
public function iCanTestAjaxActionsByTheReturnValue() { | |
$request = new sfWebRequest(new sfEventDispatcher(), | |
array('name' => 'John')); | |
$this->action->executeGoodEvening($request); | |
$eveningGreeting = $this->action-> | |
getResponse()->getContent(); | |
assertThat($eveningGreeting, | |
containsString('Good evening, John')); | |
} | |
} | |
The rest of the non-magic is in the fact that Symfony actions do not directly return the values we are interrested in. Ordinary (non-ajax) actions do not return anything they just prepare the execution of the template by storing values in a var-holder, we access it by action->getVar('name'). Ajax actions generally directly compiles the partials with parameters passed in an array and adds all that to action->response->content.
Credits go to Marc Nazarian and Sebastien Fromont without whom I still wouldn't TDD my actions.
For reference the action code
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 myActions extends sfActions { | |
public function initialize($context, $moduleName, $actionName) { | |
parent::initialize($context, $moduleName, $actionName); | |
} | |
public function executeHelloWorld(sfWebRequest $request) { | |
$this->helloMessage = "Hello ".$request->getParameter('name'); | |
} | |
public function executeGoodEvening(sfWebRequest $request) { | |
sfContext::getInstance()->getConfiguration()->loadHelpers('Partial'); | |
$greetingParameters = | |
array('name' => $request->getParameter('name')); | |
return $this->renderText( | |
get_partial('example/goodEvening', $greetingParameters)); | |
} | |
} |
and the partial used
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
<span> | |
<?php echo "Good evening, ".$name?> | |
</span> |