Testing controller

Hi,

Yii - is cool framework, but i have some troubles with him.

I need to test the controller, in the current implementation it looks like:




class MyUnitTest 

{

    ...

    public function testImport()

    {

        // Import controller

        Yii::import('application.modules.somemodule.controllers.*');


        // Create controller instance

        $controller = new DefaultController("default", Yii::app()->getModule('somemodule'));

        

        // Setup variables

        $_POST['var'] = 'testVarValueForAction';


        // Start catching output

        ob_start();


        // Run action

        $c->actionGet();


        // Check generated XML

        $this->assertEquals(ob_get_contents(), $this->XMLTestFixture);


        ob_clean();

    }

    ...

}



It’s not very cool, i think. Using ob_start for capture output and using $_POST/$_GET for passing parameters to actions.

I really like how controllers implemented in django (they are very convenient to tests): http://docs.djangoproject.com/en/1.1/topics/http/views/#topics-http-views

Why not implement something similar in Yii?

Or I did something wrong, and my test can write better?

P.S. Sorry for my English.

i think most of the time we use functional test to test controller but i do wish to to something as you did.

It’s exactly what I was searching for!

but I’m for a slightly different approach.

I’ve added this in Controller.php:




	public $viewId=null;

	public $viewData=null;

	

	/*

	 * Override of render to enable unit testing of controller

	 * */

	public function render($view,$data=null,$return=false)

	{

		$this->viewId = $view;

		$this->viewData = $data;

		

		/* if the component 'fixture' is defined we are probably in the test environment */

		if(!Yii::app()->hasComponent('fixture')){

			parent::render($view,$data,$return);

		}

		

	}



and my test is a bit different




class reviewTest extends CDbTestCase

{

	public $fixtures=array(

		'post'=>'Post'

	);


	public function setUp() {

		// Import controller

		Yii::import('application.controllers.*');

	}


	

	public function testIndex() {

		$controller = new ReviewController('review');

		

		$this->assertTrue($controller!=null);

		$this->assertInstanceOf('ReviewController', $controller);

		

		$controller->actionIndex();

		

		$this->assertTrue($controller->model!=null);

		$this->assertEquals('index', $controller->viewId);

	}

	

	

}



I’ve disabled the render() in the Test environment because I was only trying to debug the controller and also because it was giving me a lots of errors, but the next step will be enable again the render() and create a property to store the html output ready to be validated.