I am using SVN precommit hooks to validate my code standard (PSR2) before being able to commit. This works perfectly with just one exception. My unit test (PHPUnit) files exist of my bootstrap class existing of all static unit test functions, but also enables error messages above the bootstrap class definition.
The PSR2 standard will give a warning when trying to commit this, because you cannot have code that is not in a class or function in a file that contains a class definition.
Does anyone have either a way to exclude this error in my codesniffer or a way to make my code valid (without putting the code to enable my error messages in each static function of the bootstrap class)?
Here's the file:
<?php
namespace AlbumTest;
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use RuntimeException;
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);
class Bootstrap
{
protected static $serviceManager;
protected static $config;
protected static $bootstrap;
public static function init()
{
// Load the user-defined test configuration file, if it exists; otherwise, load
if (is_readable(__DIR__ . '/TestConfig.php')) {
$testConfig = include __DIR__ . '/TestConfig.php';
} else {
$testConfig = include __DIR__ . '/TestConfig.php.dist';
}
$zf2ModulePaths = array();
if (isset($testConfig['module_listener_options']['module_paths'])) {
$modulePaths = $testConfig['module_listener_options']['module_paths'];
foreach ($modulePaths as $modulePath) {
if (($path = static::findParentPath($modulePath)) ) {
$zf2ModulePaths[] = $path;
}
}
}
$zf2ModulePaths = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR;
$zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS')
? ZF2_MODULES_TEST_PATHS : '');
static::initAutoloader();
// use ModuleManager to load this module and it's dependencies
$baseConfig = array(
'module_listener_options' => array(
'module_paths' => explode(PATH_SEPARATOR, $zf2ModulePaths),
),
);
$config = ArrayUtils::merge($baseConfig, $testConfig);
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService('ApplicationConfig', $config);
$serviceManager->get('ModuleManager')->loadModules();
static::$serviceManager = $serviceManager;
static::$config = $config;
}
public static function getServiceManager()
{
return static::$serviceManager;
}
public static function getConfig()
{
return static::$config;
}
protected static function initAutoloader()
{
$vendorPath = static::findParentPath('vendor');
if (is_readable($vendorPath . '/autoload.php')) {
$loader = include $vendorPath . '/autoload.php';
} else {
$zf2Path = getenv('ZF2_PATH') ?: (defined('ZF2_PATH')
? ZF2_PATH : (is_dir($vendorPath . '/ZF2/library')
? $vendorPath . '/ZF2/library' : false));
if (!$zf2Path) {
throw new RuntimeException(
'Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.'
);
}
include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
}
AutoloaderFactory::factory(
array(
'Zend\Loader\StandardAutoloader' => array(
'autoregister_zf' => true,
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/' . __NAMESPACE__,
),
),
)
);
}
protected static function findParentPath($path)
{
$dir = __DIR__;
$previousDir = '.';
while (!is_dir($dir . '/' . $path)) {
$dir = dirname($dir);
if ($previousDir === $dir) {
return false;
}
$previousDir = $dir;
}
return $dir . '/' . $path;
}
}
Bootstrap::init();
How does your precommit-hook look like? Could you just remove the first few lines dynamically before sending the to the Codesniffer?
Another solution would be to set the error_reporting in the init of your bootstrap
Related
please l'm seeing this error if a user login to app after uploading my app to server. domain.com is currently unable to handle this request. http error 500 And everything was working fine in my local xampp server. When i checked my error-log, i saw this
PHP Fatal error: Class 'PayAssure\Models\User' not found in /home/payassur/public_html/dashboard/app/init.php on line 22.
What could have happened? please help.
Below is my init.php code.
<?php
session_start();
define('ABSPATH', dirname(__FILE__) . '/');
require_once (ABSPATH . "../vendor/autoload.php");
$GLOBALS['config'] = [
'mysql' => [
'host' => 'localhost',
'username' => 'root',
'password' => '',
'db' => 'payassure'
]
];
if (!$_SESSION['user_id']) {
header ("Location: ../index.php");
}
use PayAssure\Models\User;
use PayAssure\Models\Database;
$u = new User; //this is the line 22
$dd = new Database;
$dbb = $dd->getConnection();
$userIsBlocked = $dbb->prepare("SELECT * FROM users WHERE id = :user_id AND
blocked = '1'");
$userIsBlocked->execute(['user_id' => $_SESSION['user_id']]);
if ($userIsBlocked->rowCount() > 0) {
header("Location: userBlocked.php");
}
This is the code in models/user
<?php
namespace PayAssure\Models;
use PayAssure\Models\Database;
/**
* #package PayAssure HQ
*/
class User
{
protected $db;
public $errors;
public function __construct()
{
$d = new Database;
$this->db = $d->getConnection();
return $this->db;
}
my vendor/autoload
// autoload.php #generated by Composer
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInit3a313f3d3ce53ad02ae8da633a01a1c9::getLoader();
my autoload_real.php
<?php
// autoload_real.php #generated by Composer
class ComposerAutoloaderInit3a313f3d3ce53ad02ae8da633a01a1c9
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array(
'ComposerAutoloaderInit3a313f3d3ce53ad02ae8da633a01a1c9',
'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array(
'ComposerAutoloaderInit3a313f3d3ce53ad02ae8da633a01a1c9',
'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(
\Composer\Autoload\ComposerStaticInit3a313f3d3ce53ad02ae8da633a01a1c9::
getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
return $loader;
}
}
My composer.json file
{
"autoload": {
"psr-4": {
"PayAssure\\": "app/PayAssure"
}
},
"require-dev": {
"heroku/heroku-buildpack-php": "*",
"phpdocumentor/phpdocumentor": "2.*"
}
}
Try this
use PayAssure\Models\User as user1;
use PayAssure\Models\Database;
$u = new user1; //this is the line 22
Then see still error in 22 no line.
I'm trying to test a simple controller that authenticates a user using the LdapAdapter and using the 'ldap' array from the configuration of the Application, but phpunit is returning the following error:
Fatal error: Uncaught Error: Call to a member function get() on null in /var/www/html/app/module/Auth/src/Auth/Controller/AuthController.php:53
Stack trace:
#0 /var/www/html/app/module/Auth/test/AuthTest/Controller/AuthControllerTest.php(37): Auth\Controller\AuthController->authenticate('myuser', 'mypassword')
#1 [internal function]: AuthTest\Controller\AlbumControllerTest->testLoginAction()
#2 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(863): ReflectionMethod->invokeArgs(Object(AuthTest\Controller\AlbumControllerTest), Array)
#3 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(741): PHPUnit_Framework_TestCase->runTest()
#4 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestResult.php(608): PHPUnit_Framework_TestCase->runBare()
#5 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(697): PHPUnit_Framework_TestResult->run(Object(AuthTest\Controller\AlbumControllerTest))
#6 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php(733): PHPUnit_Framework_TestCase- in /var/www/html/app/module/Auth/src/Auth/Controller/AuthController.php on line 53
My Controller is the following:
<?php
namespace Auth\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Authentication\Adapter\Ldap as AuthAdapter;
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Result;
use Auth\Form\AuthForm;
use Auth\Model\Auth;
class AuthController extends AbstractActionController
{
public function loginAction()
{
$form = new AuthForm();
$request = $this->getRequest();
if ($request->isPost()) {
$auth = new Auth();
$form->setInputFilter($auth->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()){
$auth->exchangeArray($form->getData());
$values = $form->getData();
$result = $this->authenticate($values['username'], $values['password']);
switch($result->getCode()) {
case Result::SUCCESS:
return $this->redirect()->toRoute('home');
break;
case Result::FAILURE:
break;
}
}
}
return array('form' => $form);
}
public function authenticate($username, $password){
$options = $this->getServiceLocator()->get('Config');
$authAdapter = new AuthAdapter($options['ldap'],
'username',
'password');
$authAdapter
->setIdentity($username)
->setCredential($password);
$auth = new AuthenticationService();
$result = $auth->authenticate($authAdapter);
return $result;
}
private function debug($var){
echo '<pre>';
var_dump($var);
echo '</pre>';
exit();
}
}
The TestCase:
namespace AuthTest\Controller;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
use Zend\Authentication\AuthenticationService;
use Auth\Controller\AuthController;
class AuthControllerTest extends AbstractHttpControllerTestCase
{
protected $traceError = true;
public function setUp()
{
$this->setApplicationConfig(
include '/var/www/html/app/config/application.config.php'
);
parent::setUp();
}
public function testLoginAction()
{
#Basic Access to the page
$this->dispatch('/login');
$this->assertResponseStatusCode(200);
$data = array(
'identity' => 'myuser',
'credential' => 'mypassword',
);
$auth = new AuthController();
$auth->authenticate($data['identity'], $data['credential']);
$identity = new AuthenticationService();
$this->assertEquals($data['identity'], $identity->getIdentity());
}
}
PHPUnittest's BootStrap:
<?php
namespace AuthTest;
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use RuntimeException;
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);
/**
* Test bootstrap, for setting up autoloading
*/
class Bootstrap
{
protected static $serviceManager;
public static function init()
{
$zf2ModulePaths = array(dirname(dirname(__DIR__)));
if (($path = static::findParentPath('vendor'))) {
$zf2ModulePaths[] = $path;
}
if (($path = static::findParentPath('module')) !== $zf2ModulePaths[0]) {
$zf2ModulePaths[] = $path;
}
static::initAutoloader();
// use ModuleManager to load this module and it's dependencies
$config = array(
'module_listener_options' => array(
'module_paths' => $zf2ModulePaths,
),
'modules' => array(
'Auth'
)
);
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService('ApplicationConfig', $config);
$serviceManager->get('ModuleManager')->loadModules();
static::$serviceManager = $serviceManager;
}
public static function chroot()
{
$rootPath = dirname(static::findParentPath('module'));
chdir($rootPath);
}
public static function getServiceManager()
{
return static::$serviceManager;
}
protected static function initAutoloader()
{
$vendorPath = static::findParentPath('vendor');
if (file_exists($vendorPath.'/autoload.php')) {
include $vendorPath.'/autoload.php';
}
if (! class_exists('Zend\Loader\AutoloaderFactory')) {
throw new RuntimeException(
'Unable to load ZF2. Run `php composer.phar install`'
);
}
AutoloaderFactory::factory(array(
'Zend\Loader\StandardAutoloader' => array(
'autoregister_zf' => true,
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/' . __NAMESPACE__,
),
),
));
}
protected static function findParentPath($path)
{
$dir = __DIR__;
$previousDir = '.';
while (!is_dir($dir . '/' . $path)) {
$dir = dirname($dir);
if ($previousDir === $dir) {
return false;
}
$previousDir = $dir;
}
return $dir . '/' . $path;
}
}
Bootstrap::init();
Bootstrap::chroot();
In the functional tests it works as expected, but on php unittests the error occurs in the line 53 '$options = $this->getServiceLocator()->get('Config');'.
So, how can use or set ServiceLocator to work with phpunittests?
After so much struggling on this doubt and other tests which a controller that uses an ServiceLocator, I figure that the correct way to test a controllers Action is to Mock the object or/and his methods.
I don't feel totally comfortable with this solution, but for now, this is what it is.
An other feel is that mocking an behaviour of the code is something like that breaks the DRY principle: instead of use the real code I just create a mock that half behaves like it :S
Anyway, the following code does the job for me:
$authControllerMock = $this->getMockBuilder('Auth\Controller\AuthController')
->disableOriginalConstructor()
->getMock();
$authControllerMock->expects($this->any())
->method('authenticate')
->will($this->returnValue(true);
$serviceManager = $this->getApplicationServiceLocator();
$serviceManager->setAllowOverride(true);
$serviceManager->setService('Auth\Controller\Auth', $authControllerMock);
$this->dispatch('/usermgr');
self::assertMatchedRouteName('usermgr');
self::assertControllerClass('AuthController');
self::assertControllerName('auth\controller\auth');
self::assertResponseStatusCode('200');
I have a config file for my app but I am having trouble passing the object around as I need it to be available to my main index page and parent controller.
Currently I have to pass it as a parameter for the __Construct function in every controller I make, which certainly doesn't seem to be the best way to do it.
index.php
<?PHP
require 'config/conf.php';
$errors = array();
//Memcache the config file at some point.
define('DEBUG_MODE', 0);
define('SITE_KEY', '');
define('ROOT', 'http://manager.com/');
define('Vs', 'views/');
define('Cs', 'controllers/');
function __autoload($className) { // Autoload both controllers and models.
if (stristr($className, 'Model')) {
if (is_readable(Ms . $className . '.php')) {
include Ms . $className . '.php';
}
} else {
if (is_readable(Cs . $className . '.php')) {
include Cs . $className . '.php';
}
}
}
require 'libs/core/Controller.php';
require 'libs/core/View.php';
$Memcache = null;
if ($config['ADDITIONAL_LIBS']['MEMCACHED']) {
if (!class_exists('Memcache')) {
$errors[] = array('code' => 1, 'type' => 'error', 'title' => 'Memcached failed to load', 'msg' => 'Memcached is not installed or initialised properly.');
}
}
if ($config['SESSIONS']) {
require 'libs/core/Session.php';
}
if ($config['DATABASE']) {
define('Ms', 'models/');
require 'libs/core/Database.php';
require 'libs/core/Model.php';
}
if ($config['ADDITIONAL_LIBS']['UTIL']) {
if (file_exists('libs/extra/Util.php')) {
require 'libs/extra/Util.php';
} else {
$errors[] = loadFail('Util');
}
}
if ($config['ADDITIONAL_LIBS']['PBKDF2']) {
if (file_exists('libs/extra/PBKDF2.php')) {
require 'libs/extra/PBKDF2.php';
} else {
$errors[] = loadFail('PBKDF2');
}
}
if ($config['ADDITIONAL_LIBS']['MCAPI']) {
if (file_exists('libs/extra/MCAPI.php')) {
require 'libs/extra/MCAPI.php';
} else {
$errors[] = loadFail('MCAPI');
}
}
require 'libs/core/Router.php';
$Site = new Router($Config, $errors);
function loadFail($moduleName) {
return array('code' => 1, 'type' => 'error', 'title' => $moduleName . ' failed to load', 'msg' => $moduleName . '.php was not found in the "libs/extra/" directory.');
}
My conf file:
$Config = new Config();
$Config->set('HOME_PAGE', 'index');
$Config->set('MEMCACHE_ENABLE', true);
$Config->set('MEMCACHE_SERVERS', array(
array(
'SERVER' => 'localhost',
'PORT' => '11211'
)
));
class Config {
public $params;
function __construct() {
}
public function set($param, $value) {
$this->params[$param] = $value;
}
public function get($param) {
return $this->params[$param];
}
}
And my main controller class which I need the config object to be accesible from:
abstract class Controller {
public $view;
public $Memcache;
public function __construct($Config) {
// Autoload model if it exists...
$model = get_class($this) . 'Model';
if (is_readable(Ms . $model . '.php')) {
if ($Memcache) {
if (!$this->model = $Memcache->get($model)) {
$this->model = new $model;
}
}
}
$this->view = new View();
}
}
What is a slick and clean way to achieve what I want, which is basically to have a centralised configuration file who's parameters are available to both my main index file and parent controller?
Config is typically handled using the Registry pattern:
http://avedo.net/101/the-registry-pattern-and-php/
That's probably the most common/straightfoward way to do it. Some people prefer not to make config quite so global, in which case you would often use the Factory pattern and let the factory inject the config so that you don't have to explicitly do it with each instantiation.
I'm trying to Unit Test a ZF2 Module I've written, specifically, a service object.
But I'm getting stuck on how to get the service manager (which calls my factory object) into the test class properly. My factory object injects my modules entity object, the Doctrine entity manager, and my module's entity repository.
How do I ensure that the the factory is properly called during the Unit Test?
This is what I do in my bootstrap.php:
public static function init()
{
if (is_readable(__DIR__ . '/TestConfig.php')) {
$testConfig = include __DIR__ . '/TestConfig.php';
} else {
$testConfig = include __DIR__ . '/TestConfig.php.dist';
}
$zf2ModulePaths = array();
if (isset($testConfig['module_listener_options']['module_paths'])) {
$modulePaths = $testConfig['module_listener_options']['module_paths'];
foreach ($modulePaths as $modulePath) {
if (($path = static::findParentPath($modulePath)) ) {
$zf2ModulePaths[] = $path;
}
}
}
$zf2ModulePaths = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR;
$zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS') ? ZF2_MODULES_TEST_PATHS : '');
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService(
'ApplicationConfig',
$testConfig
);
$serviceManager->get('ModuleManager')->loadModules();
$serviceManager->setAllowOverride(true);
static::$serviceManager = $serviceManager;
}
public static function getServiceManager()
{
return static::$serviceManager;
}
And in your test class you can jus call Bootstrap::getServiceManager().
I am learning zend 2.0.6, on the initial point. I am getting the following error in phpunit test
PHPUnit 3.7.10 by Sebastian Bergmann.
Configuration read from C:\wamp\www\zf2-tutorial\module\Application\test\phpunit
.xml
Time: 0 seconds, Memory: 4.25Mb
No tests executed!
My phpunit.xml.dist is
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="Bootstrap.php">
<testsuites>
<testsuite name="ZendSkeletonApplication">
<directory>/ApplicationTest</directory>
</testsuite>
</testsuites>
</phpunit>
bootstrap is
<?php
namespace ApplicationTest;//Change this namespace for your test
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use RuntimeException;
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);
class Bootstrap
{
protected static $serviceManager;
protected static $config;
protected static $bootstrap;
public static function init()
{
// Load the user-defined test configuration file, if it exists; otherwise, load
if (is_readable(__DIR__ . '/TestConfig.php')) {
$testConfig = include __DIR__ . '/TestConfig.php';
} else {
$testConfig = include __DIR__ . '/TestConfig.php.dist';
}
$zf2ModulePaths = array();
if (isset($testConfig['module_listener_options']['module_paths'])) {
$modulePaths = $testConfig['module_listener_options']['module_paths'];
foreach ($modulePaths as $modulePath) {
if (($path = static::findParentPath($modulePath)) ) {
$zf2ModulePaths[] = $path;
}
}
}
$zf2ModulePaths = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR;
$zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS') ? ZF2_MODULES_TEST_PATHS : '');
static::initAutoloader();
// use ModuleManager to load this module and it's dependencies
$baseConfig = array(
'module_listener_options' => array(
'module_paths' => explode(PATH_SEPARATOR, $zf2ModulePaths),
),
);
$config = ArrayUtils::merge($baseConfig, $testConfig);
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService('ApplicationConfig', $config);
$serviceManager->get('ModuleManager')->loadModules();
static::$serviceManager = $serviceManager;
static::$config = $config;
}
public static function getServiceManager()
{
return static::$serviceManager;
}
public static function getConfig()
{
return static::$config;
}
protected static function initAutoloader()
{
$vendorPath = static::findParentPath('vendor');
if (is_readable($vendorPath . '/autoload.php')) {
$loader = include $vendorPath . '/autoload.php';
} else {
$zf2Path = getenv('ZF2_PATH') ?: (defined('ZF2_PATH') ? ZF2_PATH : (is_dir($vendorPath . '/ZF2/library') ? $vendorPath . '/ZF2/library' : false));
if (!$zf2Path) {
throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
}
include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
}
AutoloaderFactory::factory(array(
'Zend\Loader\StandardAutoloader' => array(
'autoregister_zf' => true,
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/' . __NAMESPACE__,
),
),
));
}
protected static function findParentPath($path)
{
$dir = __DIR__;
$previousDir = '.';
while (!is_dir($dir . '/' . $path)) {
$dir = dirname($dir);
if ($previousDir === $dir) return false;
$previousDir = $dir;
}
return $dir . '/' . $path;
}
}
Bootstrap::init();
TestConfig.php.dist is
<?php
return array(
'modules' => array(
'Application',
),
'module_listener_options' => array(
'config_glob_paths' => array(
'../../../config/autoload/{,*.}{global,local}.php',
),
'module_paths' => array(
'module',
'vendor',
),
),
);
and the thins as in documentation --http://framework.zend.com/manual/2.0/en/user-guide/unit-testing.html
where is mistake,, am i doing wrong somewhere
Remove the leading / from
<directory>/ApplicationTest</directory>
A leading / on unix means the root directory, which is not what you want. Even on Windows not.