That's because instantiating a controller will not construct required
classes used by the controller. Take a look at Disaptcher::dispatch() on
cake/dispatcher.php to see the action that takes place after a controller is
instantiated.
I need to build an article on Bakery on how to test controllers, but use
this as a guide for now (tell me later how it went.)
Suppose I have the following controller
app/controllers/articles_controller.php:
<?php
class ArticlesController extends AppController {
var $name = 'Articles';
function index($short = null) {
if (!empty($short)) {
$result = $this->Article->findAll(null, array('id',
'title'));
} else {
$result = $this->Article->findAll();
}
if (isset($this->params['requested'])) {
return $result;
}
}
}
?>
And then the following test case on
app/tests/controllers/articles_controller.test.php:
<?php
class ArticlesControllerTest extends UnitTestCase {
function testIndex() {
$result = $this->_execute('Articles', 'index');
debug($result);
}
function _execute($controller, $action = null, $params = array(),
$requested = true) {
$url = Inflector::underscore($controller) .
ife(!empty($action), '/' . $action, '') . ife(is_array($params) &&
!empty($params), '/' . join('/', $params), '');
$attributes = array();
if (!$requested) {
$attributes['return'] = true;
}
$object =& new Object();
return @$object->requestAction($url, $attributes);
}
}
?>
Ok some notes to see:
1. As you can see I've created an internal function in the test case called
_execute, that takes:
a. $controller: the controller name (e.g: 'Articles')
b. $action: the action to execute (e.g: 'index')
c. $params: a sequence of parameters to send as parameters to the
action (in order).
d. $requested: if you want to let the action use
$this->params['requested'] or instead want the rendering of the view
returned.
2. The @ on the last line of _execute() is to prevent "session previously
started" messages from being interpreted as exceptions in SimpleTest. The
downside is that any PHP exceptions thrown by your application will not be
caught by SimpleTest. This can be changed later when a change that is
pending addition to CakePHP core is implemented: ability to change define
values (particularly AUTO_SESSION in this case) through Configure::write()
calls.
3. On ArticlesController::index() I'm returning the resulting rows if
$this->params['requested'] is set.
4. You can also see that on ArticlesController::index() I added a parameter
called $short. If this parameter is set to anything other than null, then
the articles will only return id and title. Test it by changing this line on
the test case:
$this->_execute('Articles', 'index');
To:
$this->_execute('Articles', 'index', array(1));
Hope this helps.
-MI
---------------------------------------------------------------------------
Remember, smart coders answer ten questions for every question they ask.
So be smart, be cool, and share your knowledge.
BAKE ON!
blog: http://www.MarianoIglesias.com.ar
-----Mensaje original-----
De: [email protected] [mailto:[EMAIL PROTECTED] En nombre
de [EMAIL PROTECTED]
Enviado el: Lunes, 16 de Abril de 2007 11:48 a.m.
Para: Cake PHP
Asunto: Call to a member function read() on a non-object in when TEST
when I test controller,
It shows "Fatal error: Call to a member function read() on a non-
object in ... "
why the controller cant use its model now? how can solve this problem?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Cake
PHP" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---