PHPUnit test in Zend Framework 3 - unit-testing

I am trying to create a test case on the login action with 2 post parameter the code is as here
namespace UserTest\Controller;
use Application\Controller\LoginController;
use Application\Service\AuthenticationService;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\Parameters;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
class UserControllerTest extends AbstractHttpControllerTestCase
public function testIndexActionCanBeAccessed()
{
$p = new Parameters();
$p->set('username','foo');
$p->set('password','bar');
$this->getRequest()->setMethod('POST');
$this->getRequest()->setPost($p);
$this->dispatch('widget/login');
$this->assertModuleName('Application');
$this->assertControllerName(LoginController::class);
$this->assertControllerClass('LoginController');
//$this->assertMatchedRouteName('login');
}
and executing the test case from the command line the command is
./vendor/bin/phpunit
/var/www/myproject/application/module/Application/test/Controller/UserControllerTest.php
and the script throwing error that is
Fatal error: Declaration of Application\Service\AuthenticationService::authenticate() must be compatible with Zend\Authentication\AuthenticationService::authenticate(?Zend\Authentication\Adapter\AdapterInterface $adapter = NULL) in /var/www/myproject/application/module/Application/src/Application/Service/AuthenticationService.php on line 16
Please, help me to fix this issue and let me know what i am doing wrong in it

Related

How can be any service injected into WebTestCase subclass in Symfony?

Maybe I am missing something... doh, I think so, but could not find an answer to that.
WebTestCase generates this constructor sample:
public function __construct(?string $name = null, array $data = [], string $dataName = '')
{
parent::__construct($name, $data, $dataName);
}
Was trying to add my service as the first or last argument - Symfony throws an error:
Type error: Too few arguments to function Tests\AppBundle\Manager\ContactManagerTest::__construct(), 0 passed in /Library/WebServer/Documents/HEPT/vendor/bin/.phpunit/phpunit-5.7/src/Framework/TestSuite.php on line 568 and at least 1 expected in /Library/WebServer/Documents/HEPT/tests/AppBundle/Manager/ContactManagerTest.php:22
Should I somehow use container directly? Why is autowiring not working for WebTestCase classes if there is a bridge class?
WebTestCase are used in the context of PHPUnit (which has nothing to do with Symfony and its dependency injection).
They actually generate the kernel and its container, see this piece of code extracted from Symfony source code:
protected static function createClient(array $options = array(), array $server = array())
{
$kernel = static::bootKernel($options);
$client = $kernel->getContainer()->get('test.client');
$client->setServerParameters($server);
return $client;
}
This means that you can easily access the container like this:
$kernel = static::bootKernel($options);
$container = $kernel->getContainer();
Please note also that static::$kernel->getContainer() is available as soon as you created your client to make your test.

Controller Unit Test fails with SQLSTATE[42000] error

I want to unit test a controller action and have some problem toio excecute it.
The Error i got is the following:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'questionExists'
at line 1
The Method:
questionExists
is defined inside the Question Model.
My test function looks like this:
public function testView() {
$result = $this->testAction('/questions/questions/view/1', array('return' => 'vars'));
}
The Controller action i want to test looks like this:
public function view($id = null) {
if (!$this->Question->questionExists($id, 'id_virtual')) {
throw new NotFoundException(__('Invalid question'));
}
$options = array('conditions' => array('Question.id_virtual' => $id));
$this->set('question', $this->Question->find('first', $options));
}
So this is very confusing to me.
Can anybody point me to the right direction ?
Your model class is not found, CakePHP creates an instance on the fly for that table but this is not more than the basic Model class. When the code is then called it tries to call that method on an instance that is not your Question model in your app. You'll have to figure out what that happens.

PHPUnit 3.7.19 and Symfony2 broken tests

I'm developing some test for a Symfony2.0 project and running them with PHPUnit.
On my PC works fine but trying them in other environments the tests fails. I thought the problem was php version but after run them in differents environments I'm lost.
My environment is Ubuntu 12.04 and PHP 5.3.10 => Works fine.
2 PC with Ubuntu 12.10 and PHP 5.4.6:
Fatal error: Call to a member function get() on a non-object
This error is on a class which extends Symfony\Bundle\FrameworkBundle\Test\WebTestCase where is overwritten the setUp() and tearDown() methods.
public function setUp()
{
$this->client = static::createClient();
$this->client->followRedirects(true);
$crawler = $this->client->request('GET', '/admin/login');
$loginForm = $crawler->selectButton('save')->form(array(
'_username' => 'user',
'_password' => 'pass'
));
$this->client->submit($loginForm);
$this->container = $this->client->getContainer();
parent::setUp();
}
public function tearDown()
{
//Here is get() on a non-object, $this->container doesn't exists
$this->container->get('doctrine.odm.mongodb.document_manager')->getConnection()->close();
parent::tearDown();
}
2 PC, one with Ubuntu 12.10 and PHP 5.4.6 and other with Windows 7 and PHP 5.3.8:
PHP Fatal error: Call to a member function getSite() on a non-object
This error is on a class which extends the above class that has tearDown() method wrong but in this case this class works and the error is different although is related with $this->container:
//In this case, the user doesn't exists
$site = $this->container->get('security.context')
->getToken()->getUser()->getSite();
The problem is I don't know why is this. If this is related to PHP, PHPUnit(All of us have the same version), Symfony2.0 or SO.
Edit:
Ok, problems solved.
First:
Fatal error: Call to a member function get() on a non-object
Had a wrong line of code in the class which has setUp() and tearDown() methods. A line like that:
$link = $crawler->filter('a:contains("Test")')->eq(1)->link();
I had this line commented, sorry :). But I don't know why PHPUnit show me this error and not the error of link method.
Second:
PHP Fatal error: Call to a member function getSite() on a non-object
In the others environments, the test database had not been deployed.
This question will not help anyone but help me to try new things. Thanks!
It is an exected behavior for PHPUnit.
I managed to reproduce the error with the following code:
final class ExceptionErrorTest extends PHPUnit_Framework_TestCase
{
/**
* #var MyObject
*/
private $object;
public function setUp() {
throw new \RuntimeException();
$this->object = new MyObject();
}
public function testItShouldNeverBeCalled()
{
var_dump('never called');
}
public function tearDown()
{
$this->object->neverCalled();
}
}
class MyObject
{
public function neverCalled() {
return true;
}
}
// will ouput PHP Fatal error:
Call to a member function neverCalled() on a non-object in ExceptionErrorTest.php on line 22
To explain more clearly, PHPUnit will catch any exceptions triggered in the setUp method (in order for the printers to show at the end of the execution).
After that you can see that the tearDown() is called to finish the test, but since the initialization of the attribute was never reached, a PHP error is issued, and PHPUnit will never reach the code where it shows all the exceptions that occurred.
That is why you did not get the exception. To fix this, you need to make sure that any code that can throw exceptions in the setup is wrapped in a try() catch () statement like this:
public function setUp() {
try {
throw new \RuntimeException('My message');
} catch (\Exception $e) {
echo 'An error occured in the setup: ' $e->getMessage();
die;
}
$this->object = new MyObject();
}
Hope it helps someone in the future.

CakePHP fatal error: Class 'ErrorHandler' not found

I've generated testsuits via "cake bake testsuit" and used localhost/test.php for my app.
So, the is an error when I tried to run one of test (else tests are valid):
Fatal error: Class 'ErrorHandler' not found in Z:\home\prodvigator\www\cake\libs\object.php on line 201
This models and controllers are generated by scaffold and I don't think that an error is in this sources.
Using:
CakePHP 1.3
The latest SimpleTest
In my case, deleting all the files in the folder /app/tmp/cache/persistent solved the problem.
try checking the generated tests for an error that gets written at the top of the file.
sometimes i've been known to find something like this in both model and controller tests.
Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/New_York' for 'EDT/-4.0/DST' instead in /projectname/cake/console/templates/default/classes/test.ctp on line 22
In my case, the error was:
Fatal error: Uncaught Error: Class 'ErrorHandler' not found in C:\[path]\core\cake\libs\object.php on line 211
( ! ) Error: Class 'ErrorHandler' not found in C:\[path]\core\cake\libs\object.php on line 211
The error was happening to me when trying to visit http://localhost/user_accounts/index
I already had the view created at app\views\user_accounts\index.ctp with the following content:
<div>
Text from div
</div>
I had created the corresponding controller as well at app\controllers\user_accounts_controller.php:
<?php
class UserAccountsController extends AppController {
public function index() {
// Render the view in /views/user_accounts/index.ctp
$this->render();
}
}
?>
Since I was not associating a model to this controller, I was missing this: var $uses = array();. It would have saved me time if the error had been more explicit, something such as "You do not have a model associated to this controller".
The fix was:
<?php
class UserAccountsController extends AppController {
// Use this controller without a need for a corresponding Model file.
var $uses = array();
public function index() {
// Render the view in /views/user_accounts/index.ctp
$this->render();
}
}
?>

Cakephp - Testing Components - cannot find component

I am writing a component test in cakephp
here is my code
<?php
class PermissionTestCase extends CakeTestCase {
var $fixtures = array('Org');
function testsetPermission() {
$this->PermissionComponentTest = new PermissionComponent(); <---- line 5
I get this error - Fatal error: Class 'PermissionComponent' not found in /Sites/php/cake/Demo_Code/perm/app/tests/cases/components/permission.test.php on line 5
Why is it looking for the component in tests/cases ?
Also I tried moving the component into this directory and it didnt work.
Thanks
Alex
You have to include the component manually with App::import():
App::import('Component', 'Permission');