I resolved this by refactoring the Model::get_User() call out of the AccountsController code and into the Account model code. This made it testable. Thanks to Tim Koschützki http://debuggable.com/posts/implementing-different-types-for-cakes-modelfind-method:485030de-4778-456e-8400-44d84834cda3 I found the following way to override model->find:
Accounts.php includes
function find($type = string, $queryData = array()) {
switch ($type) {
case 'mine':
if (!in_array('conditions', $queryData)) {
$queryData['conditions'] =
array('id' => $this->_getUser('account_id'));
} else {
$queryData['conditions'] .=
array('id' => $this->_getUser('account_id'));
}
return parent::find('first', $queryData);
default:
return parent::find($type, $queryData);
}
}
So now my AccountsController methods can simply call
$data = $this->Account->find('mine');
and in my AccountsControllerTest I write
public function testMemberLetters() {
$this->controller = $this->generate('Accounts', array(
'models' => array(
'Account' => array('_getUser')
)
));
$this->controller->Account->expects($this->exactly(1))
->method('_getUser')
->with('account_id')
->will($this->returnValue(1));
$result = $this->testAction(
'accounts/memberLetters',
array(
'method' => 'get',
'return' => 'vars',
)
);
}