mock cake request to stub out the data function - cakephp

I have been searching all around the internet on how to mock cake requests. i want to stub out the data function to make $this->request->data('whatever') available in the controller. but something is going wrong with my test case
$Jobs = $this->generate('Tasks' , array(
'components' => array(
'RequestHandler' => array('isMobile','prefers','renderAs'))
));
// Mock CakeRequest
$request = $this->getMock('CakeRequest', array('_readInput'));
$Jobs->RequestHandler->request = $request;
$Jobs->RequestHandler->request->expects($this->any())
->method('data')->with('anything')->will($this->returnValue('test'));
$result = $this->testAction('/tasks/test/',
array('method' => 'get', 'return' => 'vars'));
whenever i call $this->request->data('anything') in the controller it returns null!
Please try to help me with this

From the PhpUnit documentation :
By default, all methods of the given class are replaced with a test double that just returns NULL unless a return value is configured using will($this->returnValue()), for instance.
When the second (optional) parameter is provided, only the methods whose names are in the array are replaced with a configurable test double. The behavior of the other methods is not changed.
So you need to either do this :
$Jobs = $this->generate('Tasks' , array(
'components' => array(
'RequestHandler' => array('isMobile','prefers','renderAs'))
));
// Mock CakeRequest
$request = $this->getMock('CakeRequest', array('_readInput'));
$Jobs->RequestHandler->request = $request;
$Jobs->RequestHandler->request->expects($this->any())
->method('_readInput')->with('anything')->will($this->returnValue('test'));
$result = $this->testAction('/tasks/test/',
array('method' => 'get', 'return' => 'vars'));
or this :
$Jobs = $this->generate('Tasks' , array(
'components' => array(
'RequestHandler' => array('isMobile','prefers','renderAs'))
));
// Mock CakeRequest
$request = $this->getMock('CakeRequest', array('data'));
$Jobs->RequestHandler->request = $request;
$Jobs->RequestHandler->request->expects($this->any())
->method('data')->with('anything')->will($this->returnValue('test'));
$result = $this->testAction('/tasks/test/',
array('method' => 'get', 'return' => 'vars'));
As I don't know cakePHP I can't tell you which is the right answer.
But according to this : http://api20.cakephp.org/view_source/controller-test-dispatcher
(line 232), you should try the former one.

Related

How to set any header in cakePHP 2.6 Controller Test

I have a Controller function, that expects the header 'X-Bla-Bla' from my JSON call. I catch the header with this:
$this->request->header('X-Bla-Bla')
Now I want to write a test for this but I can't send headers.
My test looks like this:
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
$url = Router::url(array('api' => true, 'controller' => 'test', 'action' => 'index'));
$options = array(
'return' => 'contents',
);
$result = $this->testAction($url, $options);
$this->assertNotEmpty($result);
How can I send the header?
If not, how can I still test my function?
If you set header this way in the test:
$_SERVER['HTTP_X_BLA_BLA'] = 'abc';
before calling testAction(), then your controller's action will be able to read 'abc' with expression:
$this->request->header('X-Bla-Bla')

How do I set up an adapter in zend framework 2?

this is the content of the autoload/global.php file :
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=web_builder;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
this is the content of the autoload/local.php file:
return array(
'db' => array(
'username' => 'DB_User_Name',
'password' => 'DB_Password',
,
); )
this is part of the content of module/Module.php :
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Db\Adapter\Adapter;
.........
public function getServiceConfig() {
return array(
'factories' => array(
'Application\Controller\UserController' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new Model\StickyNotesTable($dbAdapter);
return $table;
},
),
);
}
Here I really don't understand what this function do, I just copy pasted from an example. If you could explain me what does getServiceConfig function do, I will really appreaciate it.
Finally the controller content:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Db\Adapter\Adapter;
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\Sql\Select;
class UserController extends AbstractActionController{
public function __construct(Adapter $adapter) {
$this->adapter = $adapter;
}
public function loginAction(){
// here i just want to a simple select and yes I know queries will be executed
//in Model, but I want to here a simple query.
//For example in Codeigniter I can't do in model, controller, or view as well.
return new ViewModel();
}
The result of all this code is obviously an error:
Catchable fatal error: Argument 1 passed to Application\Controller\UserController::__construct() must be an instance of Zend\Db\Adapter\Adapter, none given, called in C:\xampp\htdocs\zf2\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php on line 170 and defined in C:\xampp\htdocs\zf2\module\Application\src\Application\Controller\UserController.php on line 21
Can someone post an answer to make this database or query stuff work ? thx

Download function not working CakePHP

I read the documentation regarding file downloads, however I can't seem to get this to work.
I have read through questions here as well, and have had no luck.
My function looks as follows:
public function generate($id) {
$this->layout = 'ajax';
$this->Magazine->recursive = 2;
$DistributionLists = $this->Magazine->DistributionList->find('all',
array(
'conditions' => array(
'Magazine.id' => $id
),
'order' => array(
'DistributionList.priority ASC'
)
)
);
$this->set('magazine',$DistributionLists[0]['Magazine']['magazine_name']);
$this->set(compact('DistributionLists'));
}
public function download() {
$this->viewClass = 'Media';
$params = array(
'id' => "Magazine Distribution List.doc",
'name' => "Magazine Distribution List",
'download' => true,
'extension' => 'doc',
'path' => APP . "tmp" . DS
);
$this->set($params);
unlink(APP."tmp".DS);
$this->redirect(array('action'=>'index'));
}
public function afterFilter() {
parent::afterFilter();
if($this->action == 'generate') {
$this->redirect(array('action'=>'download'));
}
}
The reason I have an afterFilter function is because the word document that needs to be downloaded is created in the view file.
Does anyone know why this doesn't work?
You have to remove the call to the redirect method in your download method because it prevents your view from getting "rendered" due to the redirect.

Cakephp testAction() is not sending a json payload to controller

I am trying to test a controller function that accepts a json payload.
As per the documentation of testAction() this can be done via setting $options['data'] to the appropriate string. Its not working for me.
See the documentation quoted here: http://api20.cakephp.org/class/controller-test-case (Please scroll down the the testAction() section).
Here is my test case.
public function testCreate(){
//Some code here
$this->testAction('/shippingbatches/create', array('data' => '[3,6]', 'method' => 'post'));
//Some more code here
}
Here is my controller function
public function create(){
debug($this->request); //This debug shows me an empty array in $this->request->data
ob_flush();
$order_ids = json_decode($this->request->data);
//Some more code here
}
The first line of the controller function is showing me an empty array in $this->request->data. If the 'data' passed from the testAction() is an actual array it comes in nice & fine. But not when it is set to a string (unlike it says in the documentation).
Here is the output of the debug.
object(Mock_CakeRequest_ef4431a5) {
params => array(
'plugin' => null,
'controller' => 'shippingbatches',
'action' => 'create',
'named' => array(),
'pass' => array(),
'return' => (int) 1,
'bare' => (int) 1,
'requested' => (int) 1
)
data => array()
query => array(
'case' => 'Controller\ShippingBatchesController'
)
url => 'shippingbatches/create'
base => ''
webroot => '/'
here => '/shippingbatches/create'
}
Please help.
Gurpreet
When passing data like that, you must receive it using CakeRequest::input().
public function create() {
$json = $this->request->input('json_decode', true);
debug($json);
}
I should note that I discovered this by reading Cake's test cases for ControllerTestCase::testAction. Reading test cases can give you insight into how Cake's internals work and give you hints on writing tests.

How to pass parameters with testAction in CakePHP2.0

I want to test a function with this header:
public function includeNumComments($posts){
Where $post is an array of data.
I wonder how can i test the method passing it an array of posts.
I have tried things like this, but it doesn't work:
$result = $this->testAction("/comments/includeNumComments/", array('data' => $posts));
$result = $this->testAction("/comments/includeNumComments/", array($posts));
Thanks
Here's the correct case, it worked for me. Hope it helps:
public function testAddUser() {
$data = array(
'User' => array(
'id' => 12,
'username' => 'testname1',
'password' => 'Pass#123!',
'email' => 'test#example.com'
)
);
$result = $this->testAction(
'/users/add',
array('data' => $data, 'method' => 'post')
);
debug($result);
}
That's not really using testAction then, because you can't pass an array via HTTP. There'd be no way to do this via a form or link on a website.
You can just test it as a normal function:
$result = $this->CommentsController->includeNumComments($posts);

Resources