I am writing unit tests for a project that use apigility but for some reason the tests classes do not recognize que namespace of the real classes.
here is a test class :
namespace Testzfnewsite\V1\Rest\SendEmail\Entity\DAO;
use PHPUnit_Framework_TestCase;
class GenericDAOTest extends PHPUnit_Framework_TestCase {
public function test_verifica_se_a_classe_existe(){
$classe = class_exists('\\zfnewsite\\V1\\Rest\\SendEmail\\Entity\\DAO\\GenericDAO');
$this->assertTrue($classe);
}
}
In this example, the class_exists function result is always false, I've checked the namespace and the class name and it is rigth, It's seens that this test class dont see the namespace of the real aplication.
This is structure of the zfnewsite module.
_zfnewsite
|
|_config
|
|_src
| |
| |_zfnewsite
| |
| |_V1
| | |
| | |_Rest
| | | |
| | | |_SendEmail
| | | | |
| | | | |_Entity
| | | | | |
| | | | | |_DAO
| | | | | |
| | | | | |_GenericDAO.php
| | | | | |_GenericDAOImpl.php
| | | | |
| | | | |_Service
| | | |
| | | |_Status
| | |
| | |_Rcp
| |
| |_Module.php
|
|_test
| |
| |_zfnewsite
| |
| |_V1
| | |
| | |_Rest
| | | |
| | | |_SendEmail
| | | | |
| | | | |_Entity
| | | | | |
| | | | | |_DAO
| | | | | |
| | | | | |_GenericDAOTest.php
| | | | | |_GenericDAOImplTest.php
| | | | |
| | | | |_Service
| | | |
| | | |_Status
| | |
| | |_Rcp
| |
| |_Bootstrap.php
|
|_Module.php
I need help to figure out what is wrong with this testing enviroment,There is diference in tests for a normal zf2 application and apigility?
This is the code for the class GenericDAO:
namespace zfnewsite\V1\Rest\SendEmail\Entity\DAO;
interface GenericDAO
{
public function save($data);
public function update($id, $data);
public function findOneBy(array $where);
public function findById($id);
public function findAll();
public function delete($id);
}
I solved this adding a bootstrap with configurations for the test enviroment,with the bootstrap file the tests files detected the real namespaces and the tests was sucessfull.
the bootstrap file:
<?php
namespace TestePsAdmin;
use Zend\Mvc;
use Zend\ServiceManager\ServiceManager;
use Zend\Mvc\Service\ServiceManagerConfig;
class bootstrap
{
static $serviceManager;
static function go()
{
// Make everything relative to the root
chdir(dirname(__DIR__));
// Setup autoloading
require_once( __DIR__ . '/../init_autoloader.php' );
// Setup autoloading
include 'vendor/autoload.php';
if (!defined('APPLICATION_PATH')) {
define('APPLICATION_PATH', realpath(__DIR__ . '/../'));
}
// Run application
$appConfig = include APPLICATION_PATH . '/config/application.config.php';
if (file_exists(APPLICATION_PATH . '/config/development.config.php')) {
$appConfig = \Zend\Stdlib\ArrayUtils::merge($appConfig, include APPLICATION_PATH . '/config/development.config.php');
}
\Zend\Mvc\Application::init($appConfig);
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService('ApplicationConfig', $appConfig);
$serviceManager->get('ModuleManager')->loadModules();
self::$serviceManager = $serviceManager;
}
static public function getServiceManager()
{
return self::$serviceManager;
}
}
bootstrap::go();
And the init_autoload is required to load Zend application path for the test enviroment:
// Composer autoloading
if (file_exists('vendor/autoload.php')) {
$loader = include 'vendor/autoload.php';
}
if (class_exists('Zend\Loader\AutoloaderFactory')) {
return;
}
$zf2Path = false;
if (is_dir('vendor/ZF2/library')) {
$zf2Path = 'vendor/ZF2/library';
} elseif (getenv('ZF2_PATH')) { // Support for ZF2_PATH environment variable or git submodule
$zf2Path = getenv('ZF2_PATH');
} elseif (get_cfg_var('zf2_path')) { // Support for zf2_path directive value
$zf2Path = get_cfg_var('zf2_path');
}
if ($zf2Path) {
if (isset($loader)) {
$loader->add('Zend', $zf2Path);
$loader->add('ZendXml', $zf2Path);
} else {
include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
Zend\Loader\AutoloaderFactory::factory(array(
'Zend\Loader\StandardAutoloader' => array(
'autoregister_zf' => true
)
));
}
}
if (!class_exists('Zend\Loader\AutoloaderFactory')) {
throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
}
with these 2 files just configured the phpunit to load the bootstrap file in the xml test config file:
<phpunit bootstrap="Bootstrap.php"
colors="true">
<php>
<server name='HTTP_HOST' value='psadmin.com' />
<server name="SERVER_NAME" value="localhost"/>
</php>
<testsuites>
<testsuite name="PricingTable Test">
<directory>../module/</directory>
</testsuite>
</testsuites>
</phpunit>
Related
in Laravel 7 which i installed and i used nWdart module, i didn't have any problem. now after migrating project to Laravel 8 i have some issue which one of them is i get ReflectionException error
when i try to running php artisan route:list i get below error:
1 [internal]:0
Illuminate\Foundation\Console\RouteListCommand::Illuminate\Foundation\Console\{closure}(Object(Illuminate\Routing\Route))
2 C:\xampp\htdocs\v8\vendor\laravel\framework\src\Illuminate\Container\Container.php:809
ReflectionException::
("Class Modules\Media\Http\Controllers\Modules\Media\Http\Controllers\Modules\Media\Http\Controllers\ImagesController does not exist")
php artisan module:list command output:
+-------------+---------+-------+----------------------------------------+
| Name | Status | Order | Path |
+-------------+---------+-------+----------------------------------------+
| Blog | Enabled | | C:\xampp\htdocs\v8\Modules/Blog |
| Media | Enabled | | C:\xampp\htdocs\v8\Modules/Media |
| Profile | Enabled | | C:\xampp\htdocs\v8\Modules/Profile |
| Radio | Enabled | | C:\xampp\htdocs\v8\Modules/Radio |
| Store | Enabled | | C:\xampp\htdocs\v8\Modules/Store |
| Ticket | Enabled | | C:\xampp\htdocs\v8\Modules/Ticket |
| UserMessage | Enabled | | C:\xampp\htdocs\v8\Modules/UserMessage |
+-------------+---------+-------+----------------------------------------+
and my routes:
<?php
use Illuminate\Support\Facades\Route;
use Modules\Media\Http\Controllers\ImagesController;
Route::prefix('panel')->group(function () {
Route::prefix('media')->group(function () {
Route::prefix('mediaResource')->group(function () {
Route::resource('imagesController', ImagesController::class);
...
});
});
});
ImagesController class:
<?php
namespace Modules\Media\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
class ImagesController extends Controller
{
public function index()
{
}
//...
public function destroy($id)
{
}
}
| panel/media/mediaResource/imagesController | imagesController.store |
Modules\Media\Http\Controllers\ImagesController#store | web |
| | GET|HEAD | panel/media/mediaResource/imagesController | imagesController.index |
Modules\Media\Http\Controllers\ImagesController#index | web |
| | GET|HEAD | panel/media/mediaResource/imagesController/create | imagesController.create |
Modules\Media\Http\Controllers\ImagesController#create | web |
| | DELETE | panel/media/mediaResource/imagesController/{imagesController}| imagesController.destroy |
Modules\Media\Http\Controllers\ImagesController#destroy| web |
| | PUT|PATCH | panel/media/mediaResource/imagesController/{imagesController}| imagesController.update |
Modules\Media\Http\Controllers\ImagesController#update | web |
| | GET|HEAD | panel/media/mediaResource/imagesController/{imagesController}| imagesController.show |
Modules\Media\Http\Controllers\ImagesController#show | web |
| | GET|HEAD | panel/media/mediaResource/imagesController/{imagesController}/edit | imagesController.edit
+--------+----------+-------------------------+-------+--------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+-------------------------+-------+--------------------------------------------------------+--------------+
| | GET|HEAD | / | | App\Http\Controllers\HomeController#index | web,auth |
| | POST | / | | App\Http\Controllers\HomeController#newsSubmit | web |
| | POST | announcement/get/fields | | App\Http\Controllers\HomeController#newsGetFields | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | login | login | App\Http\Controllers\UserController#login | web |
| | POST | login/user | | App\Http\Controllers\UserController#loginUser | web |
| | POST | notifications/get | | App\Http\Controllers\notificationsController#getNotif | web |
| | POST | notifications/read | | App\Http\Controllers\notificationsController#readNotif | web |
| | GET|HEAD | notifications/view | | App\Http\Controllers\notificationsController#index | web |
| | GET|HEAD | register | | App\Http\Controllers\UserController#register | web |
| | POST | register/user | | App\Http\Controllers\UserController#registerUser | web |
+--------+----------+-------------------------+-------+--------------------------------------------------------+--------------+
Those are all my routes:
//notifications
Route::post('/notifications/get', 'notificationsController#getNotif');
Route::post('/notifications/read', 'notificationsController#readNotif');
Route::get('/notifications/view', 'notificationsController#index');
And this is my controller:
<?php
namespace App\Http\Controllers;
use App\notifications;
use Illuminate\Http\Request;
class notificationsController extends Controller
{
public function getNotif(Request $request)
{
$id = $request->input('id');
$notifResult = notifications::orderBy('id', 'desc')->where('userID', '=', $id)->where('readed', '=', 0)->get();
$data = array(
'notifResult' => $notifResult,
'notifNumber' => count($notifResult)
);
return $data;
}
public function readNotif(Request $request)
{
$notifid = $request->input('id');
$findNotif = notifications::findOrFail($notifid);
$findNotif->readed = 1;
$findNotif->save();
}
public function index()
{
return view('notifications');
}
}
Only the index one is not working.
I am trying to display all the notifications when clicking on "View all", View all would take the user to /notifications/view which works but when I get there, I get the "Method [index] does not exist." error, and that is, I assume public function index().
SOLVED
I forgot to save the file....
Tried to clear your view and simple cache. It could be due to cache.
Vehicle.php ( app\Vehicle.php file )
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Vehicles extends Model
{
protected $primaryKey = 'serie';
protected $fillable = ['serie', 'color', 'power', 'capacity', 'speed'];
protected $hidden = ['serie'];
public function maker()
{
return $this->belongsTo('Maker');
}
}
VehicleController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Vehicle;
class VehicleController extends Controller
{
public function index()
{
$vehicles = Vehicle::all();
return response()->json(['data'=> $vehicles], 200);
}
}
Below is my route list
| Domain | Method | URI | Name | Action
| Middleware |
+--------+-----------+-----------------------------------+------------------------+-------------------------------------
-----------------+------------+
| | GET|HEAD | makers | makers.index | App\Http\Controllers\MakerController
#index | web |
| | POST | makers | makers.store | App\Http\Controllers\MakerController
#store | web |
| | PUT|PATCH | makers/{makers} | makers.update | App\Http\Controllers\MakerController
#update | web |
| | DELETE | makers/{makers} | makers.destroy | App\Http\Controllers\MakerController
#destroy | web |
| | GET|HEAD | makers/{makers} | makers.show | App\Http\Controllers\MakerController
#show | web |
| | POST | makers/{makers}/vehicle | makers.vehicle.store | App\Http\Controllers\MakersVehicleCo
ntroller#store | web |
| | GET|HEAD | makers/{makers}/vehicle | makers.vehicle.index | App\Http\Controllers\MakersVehicleCo
ntroller#index | web |
| | PUT|PATCH | makers/{makers}/vehicle/{vehicle} | makers.vehicle.update | App\Http\Controllers\MakersVehicleCo
ntroller#update | web |
| | GET|HEAD | makers/{makers}/vehicle/{vehicle} | makers.vehicle.show | App\Http\Controllers\MakersVehicleCo
ntroller#show | web |
| | DELETE | makers/{makers}/vehicle/{vehicle} | makers.vehicle.destroy | App\Http\Controllers\MakersVehicleCo
ntroller#destroy | web |
| | GET|HEAD | vehicles | vehicles.index | App\Http\Controllers\VehicleControll
er#index | web |
+--------+-----------+-----------------------------------+------------------------+-------------------------------------
when I call to myapp.com/vehicles, it show me 'Class 'App\Vehicle' not found' error. I have also Maker controller and Maker model. I can call myapp.com/makers and it also return properly. Please point me where is my weakness.
You named your class Vehicles not Vehicle. You should name it Vehicle make sure it is Vehicle.php and you will be fine.
The relationship should have the Fully Qualified Class Name in it as well:
public function maker()
{
return $this->belongsTo('App\Maker');
// or
return $this->belongsTo(Maker::class);
// assuming they are in the same namespace
}
In Laravel I have a route as follows:
Route::resource('/admin/products/', 'ProductsController');
So if I go to myapp.app:8000/admin/products/ I get all the products:
public function index()
{
$products = Product::all();
return View::make('products.index', compact('products'));
}
But if I go to myapp.app:8000/admin/products/1 where I have the following:
public function show($id)
{
return "Hi!";
}
I get an error page: NotFoundHttpException. Have I done something wrong?
In case it helps, I have attached my php artisan routes output for the relevant queries:
+--------+---------------------------------+-------------------------+-----------------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+---------------------------------+-------------------------+-----------------------------------------+----------------+---------------+
| | GET|HEAD admin/users/{month?} | | AdminController#users | admin | |
| | GET|HEAD admin/products | admin.products..index | ProductsController#index | admin | |
| | GET|HEAD admin/products/create | admin.products..create | ProductsController#create | admin | |
| | POST admin/products | admin.products..store | ProductsController#store | admin | |
| | GET|HEAD admin/products/{} | admin.products..show | ProductsController#show | admin | |
| | GET|HEAD admin/products/{}/edit | admin.products..edit | ProductsController#edit
| | PUT admin/products/{} | admin.products..update | ProductsController#update | admin | |
| | PATCH admin/products/{} | | ProductsController#update | admin | |
| | DELETE admin/products/{} | admin.products..destroy | ProductsController#destroy | admin | |
Looks like it has to do with how Laravel parses the route. Change your route to:
Route::resource('admin/products', 'ProductsController');
And the list of outputs from Artisan should change to something like this:
GET|HEAD admin/products/{products}
I have this module called 'olo' which handles all our online ordering stuff.
Now I have made a new module called 'olosec' because I wish make a different version with a slight changed flow, and some other changes in some of the controllers.
Is it possible for me to extend a controller in 'olosec' with a controller in 'olo'?
As of now I have tried
class Olosec_CartController extends Olo_CartController
Which throws an error like
Warning: include_once(Olo/CartController.php): failed to open stream:
No such file or directory in /httpdocs/library/Zend/Loader.php on line 146 Warning:
include_once(): Failed opening 'Olo/CartController.php' for inclusion.
bla bla bla (include path) bla bla bla
My directory structure is something like this (thanks tree \F \A and EditPlus++)
+---application
| +---views
| | +---scripts
| | +---layouts
| | | +---default
| | | +---admin
| | +---languages
| | +---helpers
| +---modules
| | +---admin
| | +---mobile
| | +---olo
| | | +---controllers
| | | IndexController.php
| | | MenuController.php
| | | CartController.php
| | | OrderlistController.php
| | | |
| | | +---models
| | | \---views
| | | +---helpers
| | | \---scripts
| | | +---index
| | | +---menu
| | | +---cart
| | | \---orderlist
| | \---olosec
| | +---controllers
| | | IndexController.php
| | | MenuController.php
| | | CartController.php
| | | OrderlistController.php
| | |
| | +---models
| | \---views
| | +---helpers
| | \---scripts
| | +---index
| | +---menu
| | +---cart
| | \---orderlist
| +---models
| +---controllers
| \---configs
+---library
+---public
| +---cli
| \---default
+---tests
\---data
Update
I have used this "nasty" hack which works
require_once( APPLICATION_PATH . '/modules/olo/controllers/CartController.php');
Update # Rakesh
I have this in my bootstrap..
function _initAutoloader() {
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
return $autoloader;
}
In my application.ini
autoloadernamespaces.0 = "Zend"
autoloadernamespaces.1 = "My"
autoloadernamespaces.2 = "Something"
Why not have a custom library folder for common classes
application/
library/ < for common classes
If you are using some classes not only in one controller but at many places in your project this is a good approach.
You just have to add this new application/library/ folder to your include path in your boostrap file.
Another approach is to have an action helper. But as I described the common classes folder should be a good solution. However I found some interesting resources, most of them are about cross module coding but they might help you anyway http://zend-framework-community.634137.n4.nabble.com/Code-re-use-across-modules-td668554.html and How to Use Same Models in Different Modules in Zend Framework?
Let me describe another approach
class BasicController extends Zend_Controller_Action
{
public static $variable = '';
public function init()
{
self::$variable = 'assign value';
}
}
class HomeController extends BasicController
{
public function indexAction()
{
$bioVar = parrent::$variable;
}
}
This is better than simply extending controllers because they represent actions and each action has a corresponding view script. However all your classes should be registered in autoloader.
If you have instantiate the class from Zend Autoloader, the error should go away.
You should have the following code in your bootstrap.php file:
protected function _initAutoloader()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH . '/modules',
));
return $autoloader;
}
In general, the controllers are loaded via Zend_Controller_Dispatcher, you should use Zend_Application_Module_Autoloader to instantiate the class from other controllers.